0

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

使用以下数据库模式列出员工姓名、员工编号及其各自的总收入 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;

有人可以帮助我提供一些提示或示例查询。我不确定我将如何去做。

4

1 回答 1

2

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

DISTINCT没有必要。在您使用的代码中,您DISTINCT(empName)似乎想在结果中消除重复的员工姓名。可能有两名员工具有相同的姓名,因此仅检索唯一姓名可能会将某些员工排除在您的结果之外。这就是为什么我们使用诸如empNum主键之类的东西而不是名称的原因。您实际上想要检索 和 的不同empNum组合empName

您是正确的,表中可能存在重复empNumworksOn因为给定的员工可以从事多个项目。GROUP BY会将所有具有相同empNum和的行组合在一起empName,并将它们组合成一行,从而消除对DISTINCT. (更多下文)

在这里,我修改了您的查询以包含SUM()and 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 语法。你把括号放在empNamewhich周围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 中的括号可用于对表达式进行分组,并且通常用于在处理 <、>、=、*、/ 等运算符时强制计算顺序。在单个表达式周围放置括号不会改变其值。当你认为你只是在使用DISTINCTfor 时,empName你实际上只是将表达式empName括在括号中,实际上什么也没做。

您可以通过运行此查询来测试它

SELECT empName FROM employee

这个查询

SELECT (empName) FROM employee

你会看到同样的结果。

于 2015-11-20T03:46:18.333 回答