【问题标题】:LEFT JOIN with a table twice to get separate recordsLEFT JOIN 与一个表两次以获得单独的记录
【发布时间】:2016-10-16 10:15:07
【问题描述】:

我试图通过左加入employees 表和attendance_chart 表(其中包含attendance_status 列中的存在记录)来获取所有员工的缺勤天数和当前天数

SELECT
    e.id AS employee_id,
    COUNT(present_days_chart.id) as present_days_count,
    COUNT(absent_days_chart.id) as absent_days_count

FROM
    employees e
    LEFT JOIN attendance_chart present_days_chart ON e.id = present_days_chart.attendance_for_employee_id AND present_days_chart.attendance_status = 'present'
    LEFT JOIN attendance_chart absent_days_chart ON e.id = absent_days_chart.attendance_for_employee_id AND absent_days_chart.attendance_status = 'absent'

WHERE
    e.id IN (106,138)

GROUP BY
    e.id

但是,查询在每行的present_days_count 和absent_days_count 列中不断返回相同数量的记录。

我做错了什么?

【问题讨论】:

  • rbr94 的回答是正确的。我只是补充一点,如果您想知道原因,请尝试选择 * 以查看您实际计数的内容(左连接将添加所有必要的行,复制原始表中的行)
  • 原因是:在同一个表上使用两个 LEFT JOIN 可以创建类似于 CROSS JOIN 的东西。结果是现在和缺席日子的产物。只有对于没有出席或没有缺勤天数的员工,您才会得到正确的结果。

标签: mysql join group-by left-join aggregate-functions


【解决方案1】:

尝试使用CASE WHENSUM

SELECT e.id,
       SUM(CASE WHEN days_chart.attendance_status = 'present' THEN 1 ELSE 0 END) AS present_days_count , 
       SUM(CASE WHEN days_chart.attendance_status = 'absent' THEN 1 ELSE 0 END) AS absent_days_count

FROM employees e
LEFT JOIN attendance_chart days_chart ON e.id = days_chart.attendance_for_employee_id
WHERE e.id in (106,138)
GROUP BY e.id

有了这个SUM + CASE WHEN 结构,它应该计算具有特定attendance_status 的每条记录,并在SUMGROUP BY 的帮助下总结所有计数

【讨论】:

  • 您的 WHERE 条件会将 LEFT JOIN 转换为 INNER JOIN。最好在原始查询中使用e.id
【解决方案2】:

您是否尝试过以不同的方式重写它?

    SELECT
    e.id AS employee_id,
    COUNT(present_days_chart.id) as present_days_count,
    COUNT(absent_days_chart.id) as absent_days_count

FROM
    employees e
    LEFT JOIN (SELECT * FROM attendance_chart WHERE attendance_status = 'present') AS present_days_chart ON e.id = present_days_chart.attendance_for_employee_id
    LEFT JOIN (SELECT * FROM attendance_chart WHERE attendance_status = 'absent') AS absent_days_chart ON e.id = absent_days_chart.attendance_for_employee_id

WHERE
    e.id IN (106,138)

GROUP BY
    e.id

【讨论】:

  • 不。试过了,仍然返回相同的行。
猜你喜欢
  • 1970-01-01
  • 2014-07-19
  • 2016-02-11
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多