使用 COALESCE、GROUP BY 和 ORDER BY GROUPING 问题 MySQL-已解决

Using COALESCE, GROUP BY, and ORDER BY GROUPING Issue in MySQL-SOLVED

我有一个 table 显示每个代理人和团队在几周内的收入频率。我使用 COALESCE、GROUP BY 和 ORDER BY GROUPING 语句来生成合计。我唯一的问题是它还会复制团队的名称。

    COALESCE(sales_agent.name, '')AS Agent, 
    COALESCE(sales_team.name,  '')AS Team, 
    
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=1), product.price * line_item.quantity,0)) AS 'Week 1', 
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=2), product.price * line_item.quantity,0)) AS 'Week 2', 
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=3), product.price * line_item.quantity,0)) AS 'Week 3',
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=4), product.price * line_item.quantity,0)) AS 'Week 4',
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=5), product.price * line_item.quantity,0)) AS 'Week 5',
    SUM(product.price * line_item.quantity) AS Total
    
FROM ((((line_item
INNER JOIN order_ ON line_item.order_id = order_.order_id)
INNER JOIN sales_agent ON order_.agent_id = sales_agent.agent_id)
INNER JOIN sales_team ON sales_agent.team_id  = sales_team.team_id)
INNER JOIN product ON line_item.product_id = product.product_id)
GROUP BY sales_agent.name WITH ROLLUP 
ORDER BY GROUPING(sales_agent.name),sales_agent.agent_id;

The output:

+--------+-------+---------+---------+---------+---------+---------+----------+
| Agent  | Team  | Week 1  | Week 2  | Week 3  | Week 4  | Week 5  | Total    |
+--------+-------+---------+---------+---------+---------+---------+----------+
| Galpo  | Alpha | 1590.00 | 2130.00 |    0.00 |    0.00 |    0.00 |  3720.00 |
| Rosita | Bravo |    0.00 | 2410.00 | 1485.00 |    0.00 | 2455.00 |  6350.00 |
| Harry  | Alpha |    0.00 | 1745.00 |  815.00 | 1840.00 |    0.00 |  4400.00 |
| Erika  | Bravo |    0.00 | 2000.00 |    0.00 |    0.00 |  910.00 |  2910.00 |
|        | Bravo | 1590.00 | 8285.00 | 2300.00 | 1840.00 | 3365.00 | 17380.00 |
+--------+-------+---------+---------+---------+---------+---------+----------+

New table:

SELECT CONCAT(ranges.lo, ' - ', ranges.hi) AS Revenue,
       COUNT(*) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT    0 lo,  500 hi UNION
       SELECT  501   , 1000        UNION
       SELECT 1001   , 1500       UNION
       SELECT 1501   , 2000       UNION
       SELECT 2001   , 2500 ) ranges ON product.price * line_item.quantity BETWEEN ranges.lo AND ranges.hi
GROUP BY ranges.lo, ranges.hi

UNION ALL SELECT '',
(
    SELECT 
    COUNT(product.price * line_item.quantity)
    FROM (line_item
    INNER JOIN product ON line_item.product_id = product.product_id)
);

如果每个Agent可能只属于1个团队,则不需要按团队分组。
所以改变:

COALESCE(sales_team.name,  '') AS Team

至:

CASE WHEN GROUPING(sales_agent.agent_id) = 0 THEN COALESCE(MAX(sales_team.name), '') END AS Team

此外,您还应该在 GROUP BY 子句中使用代理的 ID,并在 HAVING 子句中设置条件以仅显示最终总计:

GROUP BY sales_agent.agent_id, Agent WITH ROLLUP
HAVING GROUPING(sales_agent.agent_id) = 1 OR GROUPING(Agent) = 0
ORDER BY GROUPING(sales_agent.agent_id), sales_agent.agent_id

所以你的查询可以写成:

SELECT
    COALESCE(sales_agent.name, '')AS Agent, 
    CASE WHEN GROUPING(sales_agent.agent_id) = 0 THEN COALESCE(MAX(sales_team.name), '') END AS Team, 
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=1), product.price * line_item.quantity,0)) AS 'Week 1', 
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=2), product.price * line_item.quantity,0)) AS 'Week 2', 
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=3), product.price * line_item.quantity,0)) AS 'Week 3',
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=4), product.price * line_item.quantity,0)) AS 'Week 4',
    SUM(IF((WEEK(order_.date) - WEEK(DATE_SUB(order_.date, INTERVAL DAYOFMONTH(order_.date)-1 DAY)) + 1=5), product.price * line_item.quantity,0)) AS 'Week 5',
    SUM(product.price * line_item.quantity) AS Total
FROM line_item
INNER JOIN order_ ON line_item.order_id = order_.order_id
INNER JOIN sales_agent ON order_.agent_id = sales_agent.agent_id
INNER JOIN sales_team ON sales_agent.team_id  = sales_team.team_id
INNER JOIN product ON line_item.product_id = product.product_id
GROUP BY sales_agent.agent_id, Agent WITH ROLLUP
HAVING GROUPING(sales_agent.agent_id) = 1 OR GROUPING(Agent) = 0
ORDER BY GROUPING(sales_agent.agent_id), sales_agent.agent_id

参见demo
结果:

> Agent  | Team  |  Week 1 |  Week 2 |  Week 3 |  Week 4 |  Week 5 |    Total
> :----- | :---- | ------: | ------: | ------: | ------: | ------: | -------:
> Galpo  | Alpha | 1590.00 | 2130.00 |    0.00 |    0.00 |    0.00 |  3720.00
> Rosita | Bravo |    0.00 | 2410.00 | 1485.00 |    0.00 | 2455.00 |  6350.00
> Harry  | Alpha |    0.00 | 1745.00 |  815.00 | 1840.00 |    0.00 |  4400.00
> Erika  | Bravo |    0.00 | 2000.00 |    0.00 |    0.00 |  910.00 |  2910.00
> null   | null  | 1590.00 | 8285.00 | 2300.00 | 1840.00 | 3365.00 | 17380.00