6

我有一个按(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
4

3 回答 3

14

您将需要使用一个子查询来获取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

请参阅带有演示的 SQL Fiddle

于 2013-02-14T17:16:39.017 回答
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

于 2013-02-14T17:16:06.250 回答
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),而其他方法将返回多条记录。因此,如果第三个 B 值是 100 而不是 125,这将返回1, 100, dae,而其他解决方案将返回1, 100, abd1, 100, dae

于 2013-02-14T17:51:35.273 回答