我有两个表,一个是部门,另一个是员工。部门标识是雇员表中的外键。员工表中有一个名字和一个标志,表明该人是否是兼职。我一个部门可以有零个或多个员工。我正在尝试找出所有部门的列表,其中一个部门至少有一名员工,如果确实有至少一名员工,则所有员工都是兼职。我认为这必须是某种子查询才能实现。这是我到目前为止的内容:
SELECT dept.name
,dept.id
,employee.deptid
,count(employee.is_parttime)
FROM employee
,dept
WHERE dept.id = employee.deptid
AND employee.is_parttime = 1
GROUP BY employee.is_parttime
在此,我将非常感谢您的帮助。
答案 0 :(得分:2)
您必须在group by department
子句中使用条件将表和HAVING
联接(正确):
select d.name, d.id, count(e.id) total
from dept d inner join employee e
on d.id = e.deptid
group by d.name, d.id
having total = sum(e.is_parttime)
inner join
仅返回拥有至少1名员工的部门。
is_parttime
列(我想)是一个带有值0
或1
的标志,因此通过求和得出结果是兼职的员工人数部门,并将此数字与部门的员工总数进行比较。
答案 1 :(得分:1)
作为一个初步的建议,我建议使用JOIN
关键字表示联接,并将联接条件与过滤条件分开。这样做会使原始查询看起来像这样:
select dept.name, dept.id, employee.deptid, count(employee.is_parttime)
from employee
join dept on dept.id = employee.deptid
where employee.is_parttime = 1
group by employee.is_parttime
对于内部联接而言,它并没有太大的实际区别,但是它确实使数据的结构和查询的逻辑更加清晰。另一方面,它使外部联接有所不同,并且保持一致。
对于实际问题,是的,可以使用子查询或内联视图重写原始查询以产生请求的结果。 (从技术上讲,“内联视图”应称为FROM
子句中用作表的嵌入式查询,但是有些人将它们与子查询混在一起。)
使用子查询的示例
select dept.name, dept.id
from dept
where dept.id in (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
)
使用嵌入式视图的示例
select dept.name, dept.id
from dept
join (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
) pt_dept
on dept.id = pt_dept.deptid
在每种情况下,子查询/内联视图都会完成大部分工作。它按部门汇总员工,然后筛选组(HAVING
子句)以仅选择兼职员工人数与总人数相同的员工。当然,没有任何员工的部门也不会派代表参加。如果一个部门ID列表足以满足一个部门列表的需要,那么实际上就是您所需要的。但是,要获得部门名称,也需要将其与dept
表中的数据结合起来,如两个示例查询所示。