【问题标题】:MySQL employee databaseMySQL员工数据库
【发布时间】:2015-11-20 03:11:39
【问题描述】:

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

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

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;

有人可以帮助我提供一些提示或示例查询。我不知道该怎么做。

【问题讨论】:

  • “您的 (empName) 与 empName 相同”是什么意思?
  • DISTINCT 在这里不是一个函数,你没有调用它,并且 empName 不是一个参数。该语法恰好允许在 SELECT 子句列表达式周围使用括号。喜欢 (empNum + 7)。

标签: mysql sql sqlfiddle


【解决方案1】:

在这里,您必须使用GROUP BY 子句和SUM() 计算给定员工的总收入。

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

worksOn 表中可能存在重复的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) 中使用的语法在同一行上列出要连接在一起的表并用逗号分隔,这就是所谓的隐式连接。根据Join (SQL),随着 SQL-92 的发布,该语法已被弃用。

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

新的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),它将返回该表达式的唯一值(它只显示每个城市一次)。如果您请求多个表达式,它会返回这些表达式的唯一组合。

许多数据库引擎使用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

你会看到同样的结果。

【讨论】:

  • 查询有效。如果你有时间,你能用你自己的话阐明JOIN 是如何工作的吗?谢谢@Noah
  • 也许您可以解释一下 DISTINCT 适用于所有选定的列,而 (empName) [原文] 只是表达式 empName 周围的括号。
  • 您的查询与以下查询有什么区别:SELECT employee.empNum, employee.empName, SUM(worksOn.earningPerProject) from employee, worksOn where employee.empNum = worksOn.empNum GROUP BY employee.empNum, employee.empName;
  • @Noah 明白了。谢谢。 distinct 保留字确实具有误导性。从现在开始,我还将尝试在我的查询中使用JOIN。谢谢
猜你喜欢
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多