Есть ли способ вернуть максимальное значение столбца в SQL?

#sql #postgresql

#sql #postgresql

Вопрос:

Если у меня есть таблица…

 name | day | showers
-----|-----|--------
John | mon | 1
John | tue | 2
John | wed | 1
Pete | fri | 3
  

и я хочу вернуть таблицу каждого дня людей с наибольшим количеством душ…

 name | day | showers
-----|-----|--------
John | tue | 2
Pete | fri | 3
  

Как бы я это сделал?

Я думал, что смогу сделать…

 SELECT name, day FROM table GROUP BY name WHERE showers=max(showers)
  

но я получаю синтаксическую ошибку из-за того, что day отсутствует в предложении group by

Комментарии:

1. Что, если есть связь?

2. если есть связь, она должна называть человека дважды за каждый связанный день

Ответ №1:

Используйте distinct on :

 select distinct on (name) t.*
from t
order by name, showers desc;
  

Это возвращает ровно одну строку на имя. Если вы хотите дубликаты, если есть связи, используйте rank() или dense_rank() :

 select t.*
from (select t.*,
             rank() over (partition by name order by showers desc) as seqnum
      from t
     ) t
where seqnum = 1;
  

Ответ №2:

Вы могли бы использовать uncorrelated subquery . Это также сохранит связи

 select *
from t 
where (name, showers) in (select name, max(showers)
                          from t
                          group by name);
  

Также может быть выражено как correlated subquery

 select *
from t t1
where showers= (select max(t2.showers)
                from t t2
                where t1.name=t2.name);
  

Ответ №3:

Вы можете использовать этот запрос:

 SELECT name, days, showers
FROM test
WHERE showers =
(SELECT max(showers) FROM test i WHERE i.name = test.name)
  

Коррелированный подзапрос — это один из способов чтения каждой строки в таблице и сравнения значений в каждой строке со связанными данными. Он используется всякий раз, когда подзапрос должен возвращать другой результат или набор результатов для каждой строки-кандидата, рассмотренной основным запросом. Другими словами, вы можете использовать коррелированный подзапрос для ответа на составной вопрос, ответ на который зависит от значения в каждой строке, обрабатываемой родительским оператором.

Итак, из исходной таблицывы получаете этот результат

Итак, из исходной таблицы слева, выполнив этот запрос, вы получите результат в таблице справа