繁体   English   中英

在两列中使用 MAX() 进行 GROUP BY

[英]GROUP BY with MAX() in two columns

假设我有一个表test如下:

在此处输入图片说明

我想过滤在number2中具有最大值的行,然后在同名中在number1中具有最大值。

因此,上表中的预期结果将是第 2 行和第 4 行:

2    cuong    7    10
4    nam      3    8

选择第 2 行是因为它的number2为 10(最大值), number1为 7(5 和 7 中的最大值)。 和第 4 行类似。

结果可以通过以下方式获得:

SELECT id, name, MAX(number1), number2
FROM test
WHERE number2 IN (select max(number2) from test group by `name`)
group by `name`;

但是这个解决方案是针对我上面的假设表,在我的实际问题中,它很复杂并且必须将很多表连接在一起,WHERE子句中的子查询使得性能真的很慢。

所以,我想找到一个更简单的解决方案,它在 WHERE 子句中不使用子查询,只使用 GROUP BY,我也尝试过:

SELECT id, name, MAX(number1), number2
FROM cuong_test.test
GROUP BY `name`
HAVING number2 = MAX(number2);

但它不起作用。

这将最容易使用not exists来获得最大数字来完成:

SELECT id, name, number1, number2
FROM test t
WHERE NOT EXISTS (select 1
                  from test t2
                  where t2.name = t.name and
                        (t2.number2 > t.number2 or
                         t2.number2 = t.number2 and
                         t2.number1 > t.number1
                        )
                 );

在 MySQL 中,您也可以使用group_concat()魔法来做到这一点:

select id, name,
       substring_index(group_concat(number1 order by number2 desc), ',', 1) as number1,
       max(number2) as number2
from test t
group by name;

这比看起来更棘手。 我相信您将需要JOIN两个子查询的结果。

首先,您需要一个查询来确定满足您的第一个条件的行的 ID 号。

SELECT a.id, a.name
  FROM test AS a
  JOIN (
         SELECT MAX(number1) AS m,
                name
           FROM test
          GROUP BY name
       ) AS b ON a.name = b.name

这将查找包含每个名称的MAX(number1)的所有行的 ID 号。 您的另一个子查询为MAX(number2)执行此操作。

然后你通过 id JOIN它们以找到匹配的行......也就是说,包含两个数字的最大值。

SELECT x.id, x.name, x.m AS max_number1, y.m AS max_number2
  FROM (
        SELECT a.id, a.name
          FROM test
          JOIN (
                 SELECT MAX(number1) AS m,
                        name
                   FROM test
                  GROUP BY name
               ) AS b ON a.name = b.name
       ) AS x
  INNER JOIN (
        SELECT a.id, a.name
          FROM test
          JOIN (
                 SELECT MAX(number2) AS m,
                        name
                   FROM test
                  GROUP BY name
               ) AS b ON a.name = b.name
       ) AS y ON x.id = y.id   /* id matching */

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM