本例中having子句如何创建正确的输出?

问题描述 投票:0回答:1

HAVING
子句在 SQLite 中如何工作?我的代码可以运行并返回每个部门中收入最高的人的姓名和部门。但是,使用
HAVING
子句对我来说没有意义,因为它应该简单地过滤具有
max(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 having
1个回答
0
投票

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

仅当每组的最高(工资)为 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 的另一行,那么第一个查询的结果是:-

即由于 max(salary) 为 false (0),

other
部门的组已被删除。

而第二个查询的结果包含

other
除法:-

© www.soinside.com 2019 - 2024. All rights reserved.