假设我有一个表test
,如下所示:
我希望过滤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);
但它没有成功。
答案 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 */