假设我有以下数据库模型:
问题如下:
列出所有部门名称以及该部门的员工总数。员工总数列应重命名为“total_emps”。将列表从员 worker 数最少的部门到员 worker 数最多的部门排序。注意:您需要将某个部门包含在列表中,即使该部门当前没有分配任何员工。
这是我的尝试:
SELECT Department.deptname
(SELECT COUNT(*)
FROM Department
WHERE Department.empno = Employee.empno ) AS total_emps
FROM Department
我很确定我的解决方案不正确,因为它不包括没有员工的部门。如何使用左内连接来解决这个问题?
最佳答案
您尝试编写的查询是:
(表创建从 shree.pat18 的 sqlfiddle 修改为这个 sqlfiddle )
create table department (deptno int, deptname varchar(20));
insert into department values (1, 'a'),(2, 'b'),(3, 'c');
create table employee (empno int, deptno int);
insert into employee values (1,1),(2,1),(3,3);
SELECT d.deptname,
(SELECT COUNT(*)
FROM EMPLOYEE e
WHERE d.deptno = e.deptno ) AS total_emps
FROM DEPARTMENT d
ORDER BY total_emps ASC;
(您是从 DEPARTMENT
而不是 EMPLOYEE
开始计数,并比较 empno
而不是 deptno
。然后您就离开了去掉一个逗号。)
(系统会要求您提供每个部门的名称和员 worker 数,因此会返回该信息。实际上,如果 deptname
不唯一,我们会包含一个可能唯一的 deptno
。)
I'm pretty sure my solution is not correct as it won't include departments with no employees.
即使您的答案版本的查询(添加了缺少的逗号)也有一个外部选择,无论子选择返回什么,它都会返回每个部门的计数。所以我不知道你为什么/如何认为它不会。
如果您想使用 LEFT (OUTER) JOIN,则没有员工的 DEPARTMENT
行将被 NULL 扩展。但列的 COUNT 只计算非 NULL 行。
SELECT d.deptname, COUNT(e.empno) AS total_emps
FROM DEPARTMENT d
LEFT JOIN EMPLOYEE e
ON d.deptno = e.deptno
GROUP BY d.deptno
ORDER BY total_emps ASC;
(注意,LEFT JOIN 版本使用更多概念:通过 NULL 扩展的 LEFT JOIN、GROUP BY 以及针对非 *
的 COUNT NULL 行为。)
关于mysql - 左外连接与子查询以包含没有员工的部门,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28044805/