Mysql中联合三个表

时间:2019-07-13 14:38:26

标签: mysql sql

我有三张桌子的员工,晋升和惩罚 员工的表结构类似

Id       int
Fullname     varchar
...............
promotionDate       date

促销的表格结构如下     id int     emp_id int     DirectorateDate日期

惩罚的表结构是这样的

id                  int
emp_id              int
direcotorateDate    date

比方说,雇员表有200条记录,每个雇员一组都有晋升(服务一年后),我想获取当月获得晋升的所有雇员的列表 我可以通过此查询轻松获取列表

SELECT * 
FROM employee 
WHERE MONTH(promotionDate) = MONTH(CURRENT_DATE())
   AND YEAR(promotionDate) = YEAR(CURRENT_DATE())

我的问题是 我想从惩罚和晋升表分别计算当年每个员工获得的惩罚和晋升的数量 我做了这个查询,但是没有得到正确的结果

SELECT e.fullname , COUNT(punish.emp_id) as siza ,COUNT(pro.emp_id) as supas
  FROM emp_employee as e
  LEFT JOIN emp_punishment as punish on punish.emp_id=e.id
  LEFT JOIN emp_promotion as pro on e.id=pro.emp_id
 WHERE ((MONTH(e.promotionDate) = MONTH(CURRENT_DATE())
   AND YEAR(e.promotionDate) = YEAR(CURRENT_DATE()))
   AND ( YEAR(punish.directorate_date) = YEAR(CURRENT_DATE()) )
   AND ( YEAR(pro.directorate_date) = YEAR(CURRENT_DATE()) )
 GROUP BY e.fullname;

请帮忙。

2 个答案:

答案 0 :(得分:1)

通过直接联接3个表,您将获得重复的行。
Group by emp_id并分别汇总每个表emp_punishmentemp_promotion,并将结果加入表emp_employee

select e.fullname, coalesce(pu.siza, 0) siza, coalesce(pr.supas, 0) supas
from emp_employee as e 
left join (
  select emp_id, count(*) siza
  from emp_punishment
  where year(directorate_date) = year(CURRENT_DATE)
  group by emp_id
) pu on pu.emp_id = e.id
left join (
  select emp_id, count(*) supas
  from emp_promotion
  where year(directorate_date) = year(CURRENT_DATE)
  group by emp_id
) pr on pr.emp_id = e.id 

我仅使用以下条件:

where year(directorate_date) = year(CURRENT_DATE())

因为您的问题,您说:
我要计算每个员工在当年获得的惩罚和晋升的数量

答案 1 :(得分:0)

删除MONTH()函数,并将每个条件移动到各自的位置,而不是放在WHERE子句中,应该可以解决此问题(因为,将它们视为INNER JOIN当前样式)。

仅将公共列e.promotionDate保留在WHERE子句中:

SELECT e.fullname,
       COUNT(punish.emp_id) as siza ,
       COUNT(pro.emp_id) as supas
  FROM emp_employee as e
  LEFT JOIN emp_punishment as punish 
    ON punish.emp_id=e.id
   AND  YEAR(punish.directorate_date) = YEAR(CURRENT_DATE())
  LEFT JOIN emp_promotion as pro 
    ON e.id=pro.emp_id
   AND YEAR(pro.directorate_date) = YEAR(CURRENT_DATE()))
 WHERE YEAR(e.promotionDate) = YEAR(CURRENT_DATE())
 GROUP BY e.fullname;