#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)
Коррелированный подзапрос — это один из способов чтения каждой строки в таблице и сравнения значений в каждой строке со связанными данными. Он используется всякий раз, когда подзапрос должен возвращать другой результат или набор результатов для каждой строки-кандидата, рассмотренной основным запросом. Другими словами, вы можете использовать коррелированный подзапрос для ответа на составной вопрос, ответ на который зависит от значения в каждой строке, обрабатываемой родительским оператором.
Итак, из исходной таблицы слева, выполнив этот запрос, вы получите результат в таблице справа