[英]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.