#sql #postgresql
#sql #postgresql
Вопрос:
id | gender | max
--- -------- --------
1 | F | 5972
1 | M | 2428
2 | F | 1954
3 | M | 2093
3 | F | 2118
Я объединил 2 таблицы в таблицу выше.
Я хочу найти наивысший балл по тому же идентификатору
выходная таблица должна быть примерно такой:
id | gender | max
--- -------- --------
1 | F | 5972
2 | F | 1954
3 | F | 2118
Это может быть легко, если мне не нужно печатать пол, поскольку я могу использовать комментарий max и предложение group by .
select id, max(max)
group by id
order by id;
выше будет такое же количество строк, но проблема в том, что я не могу напечатать пол.
Ответ №1:
Это должно быть плавным:
select b.id, b.gender,b.max from (
select dense_rank() over(partition by id order by max desc) as rk,id, gender, max
from table
)
where b.rk = 1
— Добавление :
Мы можем дополнительно добавить условие типа «пол» в order by в ФУНКЦИИ РАНГА, если вам не нужны записи с несколькими полами в случае равенства max.
Комментарии:
1. Зачем вам использовать плотный ранг? (если намеренно возвращать несколько записей в случае привязки, вы должны полностью объяснить это.)
2. если я вас правильно понимаю, то да, функция dense_rank должна возвращать несколько записей в случае привязки, мы можем добавить distinct в оператор выбора, чтобы исправить его, если требуется.
3. Если две записи привязаны к самому высокому значению в
max
, но имеют разные значения вgender
, то добавлениеDISTINCT
не остановит возврат двух записей (для одного и того жеid
) . OP может потребовать , чтобы в таких случаях возвращалась только одна запись. Если это так, использованиеROW_NUMBER()
гарантирует только одну выбранную запись, хотя выбранная запись будет произвольной. В качестве альтернативы, добавление дополнительных столбцов вOVER()
предложениеORDER BY
the может предотвратить возникновение связи в первую очередь. Ни одно из этих действий не объясняется в вашем ответе.
Ответ №2:
Вы хотите distinct on
:
select distinct on (id) t.*
from t
order by id, max desc;