SQL Get Other Rows From Aggregate Function

前端 未结 3 1449
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-19 09:42

I have an aggregate function that does a group by (col A). It selects the maximum value from a set of columns(col B), but I also want to return another value from a column

相关标签:
3条回答
  • 2020-12-19 10:20

    since you haven't mention the RDBMS you are using, use this query which works on almost all 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
    
    • SQLFiddle Demo

    But if your RDBMS support window functions, you can use 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
    

    0 讨论(0)
  • 2020-12-19 10:23

    You will want to use a subquery that will get the max(b) by each A and then join that value back to your table to return the remaining columns that match the values of the subquery:

    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
    

    See SQL Fiddle with Demo

    0 讨论(0)
  • 2020-12-19 10:40

    This is a very common problem - "show me other columns on the rows matching my min()/max() aggregate criteria." On large tables, subquery strategies can become very slow, and ranking functions are sometimes not much better.

    If you're willing to get your head around it, this is by far the most performant way to handle this (though again, not the most readable):

    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
    

    You can concatenate anything you want to what you're maxing, then extract it in the outer query. Voilá.

    Note that this will return different results than the solutions posted by bluefeet and JW, in that if there are multiple matching max values per group, this method will pick a winner (the largest C) whereas the others will return multiple records. So, if the 3rd B value were 100 instead of 125, this will return 1, 100, dae whereas the other solutions would return both 1, 100, abd and 1, 100, dae.

    0 讨论(0)
提交回复
热议问题