更新:您可以单独计算每列的每个员工 ID 的行数,然后使用外连接与员工表连接。
SELECT s.id, s.name,
COALESCE(o.ordered, 0) ordered,
COALESCE(c.checkin, 0) checkin,
COALESCE(l.collected, 0) collected
FROM staff s LEFT JOIN
(
SELECT ordered id, COUNT(*) ordered
FROM orders
-- WHERE ordered_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND ordered_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
GROUP BY ordered
) o ON s.id = o.id LEFT JOIN
(
SELECT checkin id, COUNT(*) checkin
FROM orders
-- WHERE checkin_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND checkin_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
GROUP BY checkin
) c ON s.id = c.id LEFT JOIN
(
SELECT collected id, COUNT(*) collected
FROM orders
-- WHERE collected_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND collected_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH)
GROUP BY collected
) l ON s.id = l.id
或者您可以采用不同的方法先取消透视orders
表,然后按人员 ID 有条件地对其进行聚合,然后使用外连接再次将其与人员表连接
SELECT s.id, s.name,
COALESCE(p.ordered, 0) ordered,
COALESCE(p.checkin, 0) checkin,
COALESCE(p.collected, 0) collected
FROM staff s LEFT JOIN
(
SELECT id,
SUM(type = 1) ordered,
SUM(type = 2) checkin,
SUM(type = 3) collected
FROM
(
SELECT type,
CASE type
WHEN 1 THEN ordered
WHEN 2 THEN checkin
WHEN 3 THEN collected
END id
FROM orders CROSS JOIN
(
SELECT 1 type UNION ALL
SELECT 2 UNION ALL
SELECT 3
) n
-- WHERE (ordered_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND ordered_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH))
-- OR (checkin_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND checkin_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH))
-- OR (collected_date >= LAST_DAY(CURDATE() - INTERVAL 2 MONTH) + INTERVAL 1 DAY
-- AND collected_date <= LAST_DAY(CURDATE() - INTERVAL 1 MONTH))
) u
GROUP BY id
) p
ON s.id = p.id
根据您的评论,查询已更新为示例WHERE
子句以仅过滤上个月的行
样本输出:
| 身份证 | 姓名 | 订购 | 签到 | 收集 |
|----|-------|---------|---------|-----------|
| 1 | 约翰 | 1 | 1 | 1 |
| 2 | 西蒙 | 1 | 2 | 0 |
| 3 | 马克 | 0 | 0 | 0 |
| 4 | 海伦 | 2 | 1 | 3 |
这是SQLFiddle演示