ОБНОВЛЕНО: можно рассчитать число строк на каждый идентификатор сотрудника для каждого столбца по отдельности, а затем присоединиться с сотрудниками таблица с использованием внешнего соединения.
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
или вы можете использовать другой подход unpivoting orders
таблицы первый, а затем условно агрегирование его идентификатор персонала и снова присоединиться к нему со столом персонала с помощью внешнего соединения
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
статьи для фильтрации только строк за предыдущий месяц
Образец выходного сигнала:
| ID | NAME | ORDERED | CHECKIN | COLLECTED |
|----|-------|---------|---------|-----------|
| 1 | John | 1 | 1 | 1 |
| 2 | Simon | 1 | 2 | 0 |
| 3 | Mark | 0 | 0 | 0 |
| 4 | Helen | 2 | 1 | 3 |
Вот ответ SQLFiddle демо
@dgj Помогло ли это? Вам нужна дополнительная помощь по вашему вопросу? – peterm
Привет, Питер, извините за медленный ответ. Я работал над многими вещами и просто вернулся к этому. Ваш ответ выглядит идеально, я бы никогда не подумал. Это удивительно сложный ответ для того, что похоже на простой запрос. Я также собираю временные метки, когда заказываются предметы, регистрируются, собираются. Куда бы входила каждая из предложений WHERE? – dgj
^Если я говорю, что я выполнял работу в течение последней недели/месяца и т. Д. – dgj