SQL - 使用 'HAVING' 和 'EXISTS' 而不使用 'GROUP BY'
SQL - using 'HAVING' with 'EXISTS' without using 'GROUP BY'
不允许在没有 'GROUP BY' 的情况下使用 'HAVING':
SELECT *
FROM products
HAVING unitprice > avg(unitprice)
列 'products.UnitPrice' 在 HAVING 子句中无效,因为它未包含在聚合函数或 GROUP BY 子句中。
但是将相同的代码放在 'EXISTS' 下时 - 没有问题:
SELECT *
FROM products p
WHERE EXISTS (SELECT 1
FROM products
HAVING p.unitprice > avg(unitprice))
你能解释一下为什么吗?
HAVING
根据 SQL 标准和大多数数据库过滤 after 聚合。
没有GROUP BY
,仍然存在聚合。
但在您的情况下,您只需要一个子查询和 WHERE
:
SELECT p.*
FROM products p
WHERE p.unitprice > (SELECT AVG(p2.unitprice) FROM products p2);
好吧,第一个查询中的错误很明显 UnitPrice 不是聚合的一部分,也不是分组依据
而在您的第二个查询中,您正在比较 p.unitprice 来自 table“产品 p”,它不需要成为聚合或分组依据的一部分,您的第二个查询等同于:
select * from products p
where p.unitprice > (select avg(unitprice) FROM products)
这可能更清楚,sql 计算 avg(unitprice) 然后将其与产品中的 unitprice 列进行比较。
问题出在您 select 的列中:
SELECT *
和
SELECT 1
与在每一行计算的普通函数不同,聚合函数是在处理整个数据集后计算的,这意味着理论上(至少没有 GROUP BY 语句),您不能 select同一列集中的聚合函数和常规函数(即使某些 DBMS 仍然容忍这种情况)。
考虑 SUM() 时更容易看出。在返回所有行之前,您不应该访问列的总数,这会阻止您编写类似 SELECT price,SUM(price)
的内容。
GROUP BY
,现在,您可以根据给定的条件(实际上是一堆列)对行进行重新分组,这使得这些聚合函数可以在每个组的末尾进行计算整个数据集的。因此,由于在 GROUP BY
中指定的所有列对于给定组来说应该是相同的,因此您可以将它们包含在全局 SELECT
语句中。
这使我们找到了实际的失败原因:在第一次查询时,您 select 所有列。在第二个,你 select none: 只有常量 1
,它不是 table 本身的一部分。
不允许在没有 'GROUP BY' 的情况下使用 'HAVING':
SELECT *
FROM products
HAVING unitprice > avg(unitprice)
列 'products.UnitPrice' 在 HAVING 子句中无效,因为它未包含在聚合函数或 GROUP BY 子句中。
但是将相同的代码放在 'EXISTS' 下时 - 没有问题:
SELECT *
FROM products p
WHERE EXISTS (SELECT 1
FROM products
HAVING p.unitprice > avg(unitprice))
你能解释一下为什么吗?
HAVING
根据 SQL 标准和大多数数据库过滤 after 聚合。
没有GROUP BY
,仍然存在聚合。
但在您的情况下,您只需要一个子查询和 WHERE
:
SELECT p.*
FROM products p
WHERE p.unitprice > (SELECT AVG(p2.unitprice) FROM products p2);
好吧,第一个查询中的错误很明显 UnitPrice 不是聚合的一部分,也不是分组依据 而在您的第二个查询中,您正在比较 p.unitprice 来自 table“产品 p”,它不需要成为聚合或分组依据的一部分,您的第二个查询等同于:
select * from products p
where p.unitprice > (select avg(unitprice) FROM products)
这可能更清楚,sql 计算 avg(unitprice) 然后将其与产品中的 unitprice 列进行比较。
问题出在您 select 的列中:
SELECT *
和
SELECT 1
与在每一行计算的普通函数不同,聚合函数是在处理整个数据集后计算的,这意味着理论上(至少没有 GROUP BY 语句),您不能 select同一列集中的聚合函数和常规函数(即使某些 DBMS 仍然容忍这种情况)。
考虑 SUM() 时更容易看出。在返回所有行之前,您不应该访问列的总数,这会阻止您编写类似 SELECT price,SUM(price)
的内容。
GROUP BY
,现在,您可以根据给定的条件(实际上是一堆列)对行进行重新分组,这使得这些聚合函数可以在每个组的末尾进行计算整个数据集的。因此,由于在 GROUP BY
中指定的所有列对于给定组来说应该是相同的,因此您可以将它们包含在全局 SELECT
语句中。
这使我们找到了实际的失败原因:在第一次查询时,您 select 所有列。在第二个,你 select none: 只有常量 1
,它不是 table 本身的一部分。