SQL从聚合函数获取其他行

时间:2013-02-14 17:13:02

标签: mysql sql

我有一个聚合函数,它通过(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

3 个答案:

答案 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

请参阅SQL Fiddle with Demo

答案 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