我有一个如下所示的订单表
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查询是什么?
答案 0 :(得分:1)
更新:您可以单独计算每列的每个员工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
子句更新了查询,以仅过滤上个月的行
示例输出:
| 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 演示
答案 1 :(得分: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
答案 2 :(得分:0)
peterm的回答是正确的。如果没有“员工”表,下面的代码基本相同。正如peterm所示,使用COALESCE。重要的一点是进行外连接,而不是内部连接,因此计数仍会显示在报表中。
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;