我有一个带有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
,预期的答案是:
(COMPANY_ID)1 | (CUSTOMER_ID)1 | (COST)1100
(COMPANY_ID)2 | (CUSTOMER_ID)2 | (COST)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始终是错误的。如何在客户和客户之间建立联系?每家公司的身份证及其总利润?有可能吗?
感谢您的帮助。
答案 0 :(得分:2)
执行此操作的一种方法是“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()
的中间结果的长度由系统参数控制。答案 1 :(得分:0)
使用HAVING
和ALL
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) <= ALL(
SELECT SUM(p2.cost)
FROM projects p2
WHERE p2.company_id = p.company_id
GROUP BY p2.customer_id
)
答案 2 :(得分:0)
E.g:
SELECT a.*
FROM
( SELECT customer_id
, company_id
, SUM(cost) total
FROM my_table
GROUP
BY customer_id
, company_id
) a
JOIN
( SELECT company_id
, MIN(total) min_total
FROM
( SELECT customer_id
, company_id
, SUM(cost) total
FROM my_table
GROUP
BY customer_id
, company_id
) x
GROUP
BY company_id
) b
ON b.company_id = a.company_id
AND b.min_total = a.total;