我有一个聚合函数,它通过(col A)执行分组。它从一组列中选择最大值(col B),但我还想从同一行(col C)的列中返回另一个值。但如果它将3行分组,则会从列C中选择第一个值而不是具有最大值的列(MAX(col B))。
A B C
1 75 jkl
1 100 abc
1 125 dae
2 200 def
3 300 ghi
"SELECT A, MAX(B), C FROM myTable where B > 50 GROUP BY A"
returns (first row) A => 1, B => 125, C => jkl
I want it to return
A => 1, B => 125, C => dae
答案 0 :(得分:9)
您将需要使用每个max(b)
获取A
的子查询,然后将该值连接回您的表以返回与子查询的值匹配的其余列:
select *
from mytable t1
inner join
(
select A, max(b) B
from mytable
where b >50
group by a
) t2
on t1.a = t2.a
and t1.b = t2.b
where t1.b >50
答案 1 :(得分:5)
因为你没有提到你正在使用的RDBMS,所以使用这个几乎适用于所有RDBMS的查询
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT A, MAX(b) max_B
FROM tableName
WHERE b > 50
GROUP BY A
) b ON a.A = b.A AND
a.B = b.max_B
<击> 撞击>
<击>但是如果您的RDBMS支持窗口起作用,您可以使用DENSE_RANK()
SELECT A, B, C
FROM
(
SELECT A, B, C,
DENSE_RANK() OVER (PARTITION A ORDER BY B DESC) rn
FROM tableName
WHERE b > 50
GROUP BY
) a
WHERE rn = 1
击> <击> 撞击>
答案 2 :(得分:3)
这是一个非常常见的问题 - “显示符合我的min()/ max()聚合条件的行上的其他列。”在大型表上,子查询策略可能变得非常慢,并且排名函数有时不会更好。
如果您愿意了解它,这是迄今为止处理此问题的最佳方式(尽管再次,不是最易读的):
SELECT A, cast(left(val, 8) as int) AS B, substring(val, 9, 999) AS C
FROM ( SELECT A, max(str(B, 8) + C) AS val FROM myTable GROUP BY A) t
您可以将任何想要的内容连接到max
,然后在外部查询中提取它。瞧。
请注意,这将返回与bluefeet和JW发布的解决方案不同的结果,因为如果每个组有多个匹配的最大值,则此方法将选择获胜者(最大的C),而其他人将返回多个记录。因此,如果第3个B值为100而不是125,则返回 1,100,dae ,而其他解决方案将返回 1,100,abd 和 1,100,dae 。