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

Ответ 1

Вы захотите использовать подзапрос, который будет получать 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

Ответ 2

так как вы не упоминаете используемую СУБД, используйте этот запрос, который работает практически на всех РСУБД

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

Забастовкa >

Ответ 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 ing, а затем извлечь его во внешнем запросе. Вуаля.

Обратите внимание, что это приведет к возврату различных результатов, чем решения, отправленные bluefeet и JW, в том случае, если в группе имеется несколько совпадающих максимальных значений, этот метод выберет победителя (самый большой C), тогда как другие вернут несколько записей. Итак, если значение третьего B было равно 100 вместо 125, это вернет 1, 100, dae, тогда как другие решения вернут как 1, 100, abd, так и 1, 100, dae.