2013-09-26 2 views
1

У меня есть таблица заказа, которая выглядит как нижеМножественные отсчеты MySQL из таблицы заказа

order_id ordered checkin collected 
====================================== 
1   2   1   4  
2   4   2   4  
3   4   2   4  
4   1   4   1  

Это показывает, какой сотрудник заказал, проверяются и собирают каждый заказ.

Я хотел бы выполнить запрос sql, который подсчитывает, сколько заказов, проверок и коллекций производится каждым членом персонала. Это также будет ПРИСОЕДИНИТЬСЯ к таблице персонала, которая выводит имя сотрудников для каждой строки

Для сотрудника 1 (Джон) это будет 1 заказ, 1 контрольная сумма и 1 собран. Сотрудник 2 (Саймон) будет 1 заказ, 2 чека и 0 коллекций и т. Д. Для других сотрудников.

Что было бы лучшим запросом mysql для достижения этого?

ответ

1

ОБНОВЛЕНО: можно рассчитать число строк на каждый идентификатор сотрудника для каждого столбца по отдельности, а затем присоединиться с сотрудниками таблица с использованием внешнего соединения.

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 демо

+0

@dgj Помогло ли это? Вам нужна дополнительная помощь по вашему вопросу? – peterm

+0

Привет, Питер, извините за медленный ответ. Я работал над многими вещами и просто вернулся к этому. Ваш ответ выглядит идеально, я бы никогда не подумал. Это удивительно сложный ответ для того, что похоже на простой запрос. Я также собираю временные метки, когда заказываются предметы, регистрируются, собираются. Куда бы входила каждая из предложений WHERE? – dgj

+0

^Если я говорю, что я выполнял работу в течение последней недели/месяца и т. Д. – dgj

0

Вы можете использовать COUNT(*), чтобы рассчитать все заказы в таблице. Также используйте COUNT(checkin)COUNT(collected) для подсчета других полей.

Если вы пытаетесь получить подсчеты для одного пользователя, вы можете сделать это для пользователя WHERE.

SELECT 
    COUNT(order_id) AS order_count, 
    COUNT(checking) AS chcekin_count, 
    COUNT(collected) AS collected_count 
FROM 
    your table 
    WHERE staff_member = idOfStaff 

также вы можете выполнять множество отсчеты из таблицы и собрать его в одну таблицу

SELECT 
    (SELECT COUNT(order_id) FROM table WHERE staff = ?) AS staff_1_order_count, 
    (SELECT COUNT(order_id) FROM table WHERE staff = ?) AS staff_2_order_count 
0

peterm является правильным. Приведенный ниже код по существу тот же, что и таблица «персонал». Используйте COALESCE, как показала петтерма. Важный бит - это сделать внешнее соединение, а не внутреннее соединение, поэтому в вашем отчете все еще отображается 0.

select T1.member,T1.ordered_count,T2.checkin_count, collected_count 
from (
    select ordered as "member", count(*) as "ordered_count" 
    from orders group by ordered 
) as T1 
left join (
    select checkin as "member", count(*) as "checkin_count" 
    from orders 
    group by checkin 
) as T2 on T1.member=T2.member 
left join (
    select collected as "member", count(*) as "collected_count" 
    from orders 
    group by collected 
) as T3 on T2.member=T3.member; 
Смежные вопросы