我有3张桌子
员工=> e_id(P.K),dep_id(F.k)
部门=> d_id(P.K)
出勤=> id(P.K),date_of_absence(日期),e_id_f(F.K)
我希望在一段时间内获得某个部门缺席员工的数量。
我创建了一个名为MyDates的表
CREATE TABLE MyDates (mydate date);
此程序用日期填写MyDates表
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
WHILE dateStart <= dateEnd DO
INSERT INTO MyDates (mydate) VALUES (dateStart);
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;
然后我打电话给MyDates填写日期CALL填写日期(&#39; 2017-01-01&#39;,&#39; 2017-03-31&#39;);
然后我做了这个选择声明:
select mydates.mydate, count(attendance.date_of_absence)
from mydates left join attendance on
mydates.mydate = attendance.date_of_absence
where mydates.mydate Between "2017-01-01" AND "2017-01-31"
group by mydates.mydate
这个查询得到我所需要的但是对于所有部门,但是某个部门的行数不正确
select mydates.mydate, count(attendance.date_of_absence)
from mydates
left join attendance on mydates.mydate = attendance.date_of_absence
inner join employee on attendance.e_id_f = employee.e_id
where mydates.mydate Between "2017-01-01" AND "2017-01-31" AND employee.dep_id = 4
group by mydates.mydate;
这是截图 IMG
答案 0 :(得分:0)
我可以看到您的查询有3个问题。第一个2导致丢弃没有找到匹配记录的日期,第三个可能意味着您得到错误的计数:
inner join employee on attendance.e_id_f = employee.e_id
- 如果一天没有匹配记录,那么attendance.e_id_f
将在当天为空。内连接将从结果集中删除此记录。解决方案:也可以将此连接设为左侧。
AND employee.dep_id = 4
- 这只会保留结果集中的记录,这些记录具有与之关联的员工记录,因此如果您有0缺席的日期,此条件将从结果集中删除它。解决方案:在连接条件中包含此条件。
count(attendance.date_of_absence)
- 计算出勤表中的出现次数,这在添加第二次左连接后将不正确。解决方案:改为使用count(employee.dep_id)
。
修改后的查询:
select mydates.mydate, count(employee.dep_id)
from mydates
left join attendance on mydates.mydate = attendance.date_of_absence
left join employee on attendance.e_id_f = employee.e_id AND employee.dep_id = 4
where mydates.mydate Between "2017-01-01" AND "2017-01-31" group by mydates.mydate
替代解决方案是使用嵌套连接,您可以专门指示MySQL首先执行attendance inner join employee
连接。您仍然需要将employee.dep_id = 4
条件移动到连接条件:
select mydates.mydate, count(attendance.date_of_absence)
from mydates
left join (attendance inner join employee)
on mydates.mydate = attendance.date_of_absence
and attendance.e_id_f = employee.e_id
and employee.dep_id = 4
where mydates.mydate Between "2017-01-01" AND "2017-01-31"
group by mydates.mydate
在后一种情况下,嵌套的内部联接确保仅返回属于dep_id = 4
的那些出勤记录,然后将这些记录保留在日期表中。在这种情况下,无需更改您正在计算的字段。