我正在学习SQL,并在MySQL中创建了以下数据集:

Create table Departments (DepartmentID int primary key, Name text);

insert into Departments values
(1001,'SRO'),
(2001,'Drs'),
(3001,'Accounting');

Create table Employees 
(
  EmployeeID int not null, 
  DepartmentID int not null,
  ManagerID int,
  Name varchar(50) not null,
  Salary int not null,
  primary key(EmployeeID),
  foreign key (DepartmentID)
    references Departments(DepartmentID)
 );

insert into Employees values
(68319,1001,NULL,'Kayling','6000.00'),
(66928,3001,68319,'Blaze','2750.00'),
(67832,1001,68319,'Clare','2550.00'),
(65646,2001,68319,'Jonas','2957.00'),
(67858,2001,65646,'Scarlet','3100.00'),
(69062,2001,65646,'Frank','3100.00'),
(63679,2001,69062,'Sandrine','900.00'),
(64989,3001,66928,'Adelyn','1700.00'),
(65271,3001,66928,'Wade','1350.00');

我想找出每个部门的最高工资,研究了我看到的许多文章,建议以这种形式运行MAX:

SELECT max(Salary),DepartmentID 
FROM Employees
GROUP BY DepartmentID;

然而,根据答案here中描述的操作顺序,

FROM, including JOINs
WHERE
SELECT the row  obtained  by from and where in a temporary area for others 
        operation (and build the column alias)
DISTINCT
GROUP BY
HAVING
ORDER BY
LIMIT and OFFSET
return the final result

GROUP BY之前调用MAX函数,这意味着在执行GROUP BY之前,MAX将在整个表中运行,根据我的理解,这应该导致出现单个最大值across the table,该值应该是6000.然而,情况并非如此,我确实看到的结果令人困惑,我想要的 struct 是正确的:

max(Salary) DepartmentID
6000        1001
3100        2001
2750        3001

不知何故,MAX函数在GROUP BY之后工作,但也在由于GROUP BY删除多个组行而丢失所有行之前工作.

如果我继续这样理解,就会给我带来更多的问题.

如果对SELECT执行GROUP BY操作before,则GROUP BY将删除每个DepartmentID的所有行,只保留一行randomly chosen,这意味着当SELECT中的MAX函数有机会运行时,它将只看到一个工资值,该值可以是任何值,而不是每个部门的最大值.

我错过了什么让我的理解变得复杂的地方?

推荐答案

当我们判断查询时,我们需要理解的是,group by有一个投影before,group by有一个投影after.

group by之前,我们定义了我们将从什么关系进行分组.这可以是整个表、投影表(列与最初定义的不同)、筛选表(where子句和联接),甚至是特别表(如(select 1 as foo union select 2 as foo union select 3 as foo)).

GROUP BY是汇总结果的过程.这意味着,在对构成结果的记录进行完全判断之前,像MAX()MIN()AVG()这样的内容(尽管有索引)在默认情况下是不可判断的.

那么,你将如何判断某物的最大值,例如:

(伪码)(伪码)

max <- -infinity
for r of rows do
    if max < r.yourfield then max <- r.yourfield
end for

这就是发生在你身上的事情.MAX(yourfield)表示对于该字段,您需要找出结果集的最大值是多少.如果有GROUP BY,那么伪代码就会变成这样:

max <- -infinity
for r of rows do
    if max[group(row)] < r.yourfield then max[group(row)] <- r.yourfield
end for

因此,记录被取消分组并正在处理中.随着集团的建立,单独的聚合值也在单独建立.

Mysql相关问答推荐

在联合查询中使用GROUP BY和ORDER BY

SQL - Select 复合主键,条件为其中一个主键

使用复合主键更新后的MySQL触发器失败

如何使用sql查询在日期列中按值和最大值分组的表中添加列?

如何根据 R 中的价格范围将数据从一列复制到新列?

检索按键列值分组的最新日期 (MySql)

为什么以及如何将 Django filter-by BooleanField 查询转换为 SQL WHERE 或 WHERE NOT 而不是 1/0?

为什么 MySQL 不使用索引进行简单的SELECT * FROM Table WHERE field='value'查询?

MySQL 8.0.30 正则表达式词匹配特殊字符

多个驱动器上的 MYSQL 数据

创建表时我的 SQL 语句有什么问题

了解 SQL 中的元组语法

我将如何构建一个 SQL 查询来从交易表中 Select 第一次存款、第二次存款和额外存款

如何过滤表格,以便它显示最新的数据?

判断一对记录是否属于多个组ID

MySQL如何为数据库中的所有表生成DDL

MySQL更新查询与左连接和分组依据

如何将本地托管的 MySQL 数据库与 docker 容器连接

如何在执行 sql 脚本时 echo 打印语句

cron 启动的 mysqldump 和密码安全