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.