GROUP BY与MAX()在两列中

时间:2014-04-16 10:28:47

标签: mysql sql

假设我有一个表test,如下所示:

enter image description here

我希望过滤number2中最大的行,然后使用相同名称过滤number1中的最大行。

因此,上表中的预期结果将是行ID 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);

但它没有成功。

2 个答案:

答案 0 :(得分:1)

最容易使用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() magic:

执行此操作
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;

答案 1 :(得分:1)

这比它看起来更棘手。我相信您需要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 */