我有一个包含 PROJECT_ID、CUSTOMER_ID、COMPANY_ID 和 COST 列的 PROJECTS 表。 一位客户可能在不同的公司拥有一个或多个项目。 我想要的是选择一个客户,为每个公司产生最小的收入。
例如如果表格看起来像这样
project_id customer_id company_id cost
1 1 1 1000
2 1 1 100
3 2 1 3000
4 1 2 300
5 2 2 100
,预期的答案是:
(公司编号)1 | (CUSTOMER_ID) 1 | (成本) 1100
(公司编号)2 | (CUSTOMER_ID) 2 | (成本) 100
因为第一个客户总共产生了 1000 + 100 = 1100。
我的查询如下所示:
SELECT TABLE1.company_id, TABLE1.customer_id, MIN(profit)
FROM (
SELECT company_id, customer_id, SUM(projects.cost) AS profit
FROM projects
GROUP BY company_id,customer_id
) AS TABLE1
GROUP BY TABLE1.company_id;
它计算的是 MIN 利润,但是 CUSTOMER_ID 列中的 ID 总是错误的。如何在每个公司的客户 ID 和他们的总利润之间建立联系?可能吗?
感谢您的帮助。
最佳答案
这样做的一种方法是“hack”,因为它使用字符串操作来获取您想要的值:
SELECT cc.company_id,
SUBSTRING_INDEX(GROUP_CONCAT(cc.customer_id ORDER BY profit ASC), ',', 1) as customer_id,
MIN(profit)
FROM (SELECT p.company_id, p.customer_id, SUM(p.cost) AS profit
FROM projects p
GROUP BY p.company_id, p.customer_id
) cc
GROUP BY cc.company_id;
MySQL 中的替代方案是这样的:
SELECT p.company_id, p.customer_id, SUM(p.cost) AS profit
FROM projects p
GROUP BY p.company_id, p.customer_id
HAVING SUM(p.cost) = (SELECT SUM(p2.cost)
FROM projects p2
WHERE p2.company_id = p.company_id
ORDER BY SUM(p2.cost) ASC
LIMIT 1
);
这两个版本略有不同:
- 第一个总是会返回一个客户,即使有联系也是如此。
- 第一个会将
company_id
转换为字符串。 - 第一个可能会遇到溢出情况,因为
group_concat()
的中间结果的长度由系统参数控制。
关于mysql - 如何找到每个组的 MIN 值并选择整行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47018059/