在此示例中,having 子句如何创建正确的输出?

How is the having clause creating the correct output in this example?

提问人:Srihari P 提问时间:8/9/2023 最后编辑:user4157124Srihari P 更新时间:8/10/2023 访问量:33

问:

该子句在SQLite中如何工作?我的代码可以工作,并返回每个部门中收入最高的人的姓名和部门。但是,使用该子句对我来说没有意义,因为它应该简单地过滤具有 false 值的组:HAVINGHAVINGmax(salary)

CREATE TABLE salaries AS
  SELECT 'Alpha' as name, 'computer' as division, 500 as salary UNION
  SELECT 'Bravo', 'computer', 600 UNION
  SELECT 'Charlie', 'accounting', 200 UNION
  SELECT 'Delta', 'accounting', 300 UNION
  SELECT 'Echo', 'management', 800 UNION
  SELECT 'Foxtrot', 'management', 900;

SELECT name, division FROM salaries GROUP BY division HAVING max(salary);

为什么上述查询会生成与此查询相同的输出:

SELECT name, division
FROM salaries AS s
WHERE salary = (
  SELECT MAX(salary)
  FROM salaries
  WHERE division = s.division
);
sql SQLite(SQL 拥有

评论


答:

0赞 MikeT 8/9/2023 #1

但是,使用 HAVING 子句对我来说没有多大意义,因为它应该简单地过滤掉 max(salary) 的 false 值的组

只有当每组的最高(工资)为 0 时,才会根据:-

如果指定了 HAVING 子句,则将作为布尔表达式对每组行计算一次。如果计算 HAVING 子句的结果为 false,则丢弃该组。如果 HAVING 子句是聚合表达式,则在组中的所有行中计算该子句。如果 HAVING 子句是非聚合表达式,则根据从组中任意选择的行对其进行计算。HAVING 表达式可以引用不在结果中的值,甚至是聚合函数。https://www.sqlite.org/lang_select.html#generation_of_the_set_of_result_rows

因此,如果您使用,例如:-

CREATE TABLE salaries AS
  SELECT 'Alpha' as name, 'computer' as division, 500 as salary UNION
  SELECT 'Bravo', 'computer', 600 UNION
  SELECT 'Charlie', 'accounting', 200 UNION
  SELECT 'Delta', 'accounting', 300 UNION
  SELECT 'Echo', 'management', 800 UNION
  SELECT 'Foxtrot', 'management', 900 UNION
  SELECT 'Hotel', 'other', 0; /*<<<<<<<<<< ADDED for demo */
  
SELECT name, division, max(salary) AS msal FROM salaries GROUP BY division HAVING max(salary);


SELECT name, division, salary AS msal
FROM salaries AS s
WHERE salary = (
  SELECT MAX(salary)
  FROM salaries
  WHERE division = s.division
);
  • 即另一行,另一个部门的工资为 0,那么第一个查询的结果是:-

enter image description here

即,由于 max(salary) 为 false (0),该部门的组已被删除。other

虽然第二个查询的结果包括以下部分:other

enter image description here