如何找到每个组的MIN值并选择整行?

时间:2017-10-30 14:43:25

标签: mysql sql database

我有一个带有PROJECT_ID,CUSTOMER_ID,COM​​PANY_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始终是错误的。如何在客户和客户之间建立联系?每家公司的身份证及其总利润?有可能吗?

感谢您的帮助。

3 个答案:

答案 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)

使用HAVINGALL

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;