使用 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
我有一个 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