Как мне выбрать столбец, который не используется group by?

#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;