MySQL 员工数据库

MySQL employee database

我在设计执行以下操作的查询时遇到问题:

使用以下数据库架构列出员工姓名、员工编号及其各自的总收入:

department(primary key(deptName), deptName, deptCity) 
employee(primary key(empNum), empName, empCity)
project(primary key(projectNum), projectName, budget)
worksOn(foreign key(empNum), foreign key(projectNum), deptNum, jobTitle, startDate, earningPerProject) 

我能够显示员工姓名和员工编号,但是当涉及到每个员工的 earningPerProject 总数时,我就迷路了。

有些员工不止一次列出,我意识到我必须使用聚合函数 SUM()COUNT() , 但我还没有找到成功的方法。

这是我目前的情况:

SELECT DISTINCT(empName), employee.empNum, earningPerProject FROM employee, worksOn
WHERE worksOn.empNum = employee.empNum;

有人可以帮助我提供一些提示或示例查询。我不确定我会怎么做。

此处您必须使用 GROUP BY 子句和 SUM() 来计算给定员工的总收入。

DISTINCT 没有必要。在您的代码中,您使用了 DISTINCT(empName) ,看起来您想要消除结果中重复的员工姓名。可能有两名员工同名,因此仅检索唯一名称可能会使某些员工不在您的结果中。这就是为什么我们使用 empNum 之类的东西作为主键而不是名称。您实际上想要检索 empNumempName.

的不同组合

worksOn table 中可以有重复的 empNum 是正确的,因为给定的员工可以从事多个项目。 GROUP BY 会将具有相同 empNumempName 的所有行组合在一起,并将它们组合成一行,从而消除对 DISTINCT 的需要。 (更多内容在下方)

我已经修改了您的查询以包含 SUM()GROUP BY

SELECT employee.empNum, employee.empName, SUM(worksOn.earningPerProject)
  FROM employee, worksOn
 WHERE employee.empNum = worksOn.empNum
 GROUP BY employee.empNum, employee.empName;

加入

FROM 子句 (FROM employee, worksOn) 中使用的语法在同一行列出要连接在一起的 table,逗号分隔就是所谓的隐式连接。根据 Join (SQL).

,随着 SQL-92 的发布,此语法已被弃用

最佳实践要求您切换到使用称为显式连接的新语法,方法是使用 JOIN 关键字和添加的 ON 关键字来描述 link 之间的 tables.

新的 JOIN 语法在功能上等同于旧的隐式连接语法。两者产生相同的结果。

SELECT employee.empNum, employee.empName, SUM(worksOn.earningsPerProject)
  FROM employee
  JOIN worksOn ON employee.empNum = worksOn.empNum
 GROUP BY employee.empNum, employee.empName;

不同的

DISTINCT 是一个 SQL 关键字,它根据 SELECT 列表中的表达式消除重复的结果行。如果您只请求一个表达式 (SELECT empCity FROM employee),它会 returns 该表达式的唯一值(它只显示每个城市一次)。如果您请求多个表达式,它 returns 这些表达式的唯一组合。

许多数据库引擎使用 GROUP BY 来计算 DISTINCT 结果,因此将它们一起使用通常是多余的。

您的查询包含一些不幸的合法 SQL 语法。您在 empName 两边加上括号,结果是 SELECT DISTINCT (empName), employee.empNum, ...。此语法具有误导性,因为 DISTINCT 是关键字而不是函数,并且 DISTINCT 未使用此处的括号。当使用 DISTINCT 时,它适用于 SELECT 中的所有表达式。在这种情况下,删除括号不会改变意思,但它确实使意思更清楚。

这三个查询是等价的:

SELECT DISTINCT empName, employee.empNum, ...

SELECT DISTINCT (empName), employee.empNum, ...

SELECT DISTINCT empName, (employee.empNum), ...

SQL 中的圆括号可用于对表达式进行分组,通常用于在处理 <、>、=、*、/ 等运算符时强制计算的顺序。在单个表达式周围放置括号不会更改其值。当您认为您只是将 DISTINCT 用于 empName 时,您实际上只是将表达式 empName 括在括号中,实际上什么也没做。

您可以通过 运行 这个查询

来测试
SELECT empName FROM employee

和这个查询

SELECT (empName) FROM employee

你会看到同样的结果。