sql - SQL - 同一张表 - 有 c2.Country <> c.Country - 需要了解
问题描述
我尝试了以下 SQL 查询,但不明白括号中的最后一部分
SELECT COUNT(c2.CustomerID)
FROM Customers AS c2
GROUP BY c2.Country
HAVING c2.Country <> c.Country
作品。
SELECT COUNT(c.CustomerID) AS cnt, c.Country
FROM Customers c
GROUP BY c.Country
HAVING cnt NOT IN (SELECT COUNT(c2.CustomerID)
FROM Customers AS c2
GROUP BY c2.Country
HAVING c2.Country <> c.Country);
前三行给了我国家名称和他们客户 ID 的数量。
例如:
Argentina 3
Belgium 3
Brazil 9
IRAN 2
Turkey 2
最后一部分
SELECT COUNT(c2.CustomerID)
FROM Customers AS c2
GROUP BY c2.Country
HAVING c2.Country <> c.Country
仅返回具有相同数量的其他国家/地区的国家/地区的 count 客户 ID。这是如何运作的?
例如:
3
2
不要给巴西9分。
我不太明白 HAVING 查询的第二个条件是否有效:拥有 c2.Country <> c.Country。我知道 c2.Country <> c.Country 是什么意思。我不明白粗线是如何工作的。
当括号中的查询通过“HAVING NOT IN”链接到原始查询时,该查询实质上是比较查询第一部分的值和第二部分的值(阿根廷 3、比利时 3、伊朗 2、土耳其 2)并将返回第二个查询中不存在的所有行,即巴西 9。
解决方案
鉴于:
CREATE TABLE Customers (
CustomerID int PRIMARY KEY AUTO_INCREMENT
, Country VARCHAR(20)
);
INSERT INTO Customers (Country) VALUES
('Argentina')
, ('Argentina')
, ('Argentina')
, ('Belgium')
, ('Belgium')
, ('Belgium')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('Brazil')
, ('IRAN')
, ('IRAN')
, ('Turkey')
, ('Turkey')
;
和 SQL:
SELECT COUNT(c.CustomerID) as cnt, c.Country
FROM Customers c
GROUP BY c.Country
Having cnt NOT IN (SELECT COUNT(c2.CustomerID) FROM Customers AS c2 GROUP BY c2.Country Having c2.Country <> c.Country)
;
上面的 SQL 具有dependent / correlated
行为,其中子查询具有对外部行 ( c.Country
) 的引用。
从功能上讲,这意味着我们为外部GROUP BY
子句生成的每一行执行子查询。
这也意味着我们必须小心,仅使用在功能上依赖于外部GROUP BY
项的表达式来引用外部行。
首先,让我们看一下外部逻辑的整个结果GROUP BY
(没有HAVING
逻辑):
国家 | cnt |
---|---|
阿根廷 | 3 |
比利时 | 3 |
巴西 | 9 |
伊朗 | 2 |
火鸡 | 2 |
让我们仅以一个外行为例:
国家 = '伊朗',cnt = 2
当我们为此行执行子查询时,我们实际上是这样做的:
(SELECT COUNT(c2.CustomerID) FROM Customers AS c2 GROUP BY c2.Country Having c2.Country <> 'IRAN')
这会生成一个列表(仅选择 cnt):
国家 | cnt |
---|---|
阿根廷 | 3 |
比利时 | 3 |
巴西 | 9 |
火鸡 | 2 |
但是由于该HAVING
条款而没有“伊朗”:Having c2.Country <> c.Country
产生的列表cnt
是:3、3、9、2
现在,由于外行与 关联cnt = 2
,该NOT IN
子句从最终结果中消除了外行。
当我们处理这些外行时,土耳其、阿根廷和比利时也发生了同样的事情。
唯一剩下的外排是:巴西cnt = 9
如果您需要更多信息,请与我们联系。
推荐阅读
- android - Error: Program type already present: org.intellij.lang.annotations.JdkConstants$PatternFlags 2
- javascript - How can i filter array on object in javascript
- xamarin - Xamarin 表单中的数据绑定条目
- javascript - Javascript将数组转换为以数组属性为键的映射,并将相应的重复键值存储为数组
- c# - Excel UDF takes empty parameter in unwanted second invocation
- laravel - 无法在 laravel 刀片文件中加载图像
- vue.js - Unable to import multiple component in vuejs with Typescript
- git - 使用 SSH 协议克隆 Bitbucket
- java - Seems that methods of maven repository can not be called from end-product
- python - 无法移动/删除电子邮件但可以复制它