PostgreSQL MAX и GROUP BY
у меня есть таблица с id, year и count.
я хочу получить MAX(count) для каждого id и сохранить year когда это случится, поэтому я делаю этот запрос:
SELECT id, year, MAX(count)
FROM table
GROUP BY id;
к сожалению, это дает мне ошибку:
ошибка: столбец "таблицы.год " должен появиться в предложении GROUP BY или быть используется в агрегатной функции
поэтому я пытаюсь:
SELECT id, year, MAX(count)
FROM table
GROUP BY id, year;
но тогда это не сделать MAX(count), это просто показывает таблицу такой, какая она есть. Я полагаю, потому что при группировке по year и id, он получает максимум за id этого конкретного года.
Итак, как я могу написать этот запрос? Я хочу получить ids MAX(count) и год, когда это произойдет.
2 ответов
select *
from (
select id,
year,
thing,
max(thing) over (partition by id) as max_thing
from the_table
) t
where thing = max_thing
или:
select t1.id,
t1.year,
t1.thing
from the_table t1
where t1.thing = (select max(t2.thing)
from the_table t2
where t2.id = t1.id);
или
select t1.id,
t1.year,
t1.thing
from the_table t1
join (
select id, max(t2.thing) as max_thing
from the_table t2
group by id
) t on t.id = t1.id and t.max_thing = t1.thing
или (так же, как и предыдущий с другой нотацией)
with max_stuff as (
select id, max(t2.thing) as max_thing
from the_table t2
group by id
)
select t1.id,
t1.year,
t1.thing
from the_table t1
join max_stuff t2
on t1.id = t2.id
and t1.thing = t2.max_thing
самый короткий (и, возможно, самый быстрый) запрос с DISTINCT ON, расширение PostgreSQL стандарта SQL DISTINCT статья:
SELECT DISTINCT ON (1)
id, count, year
FROM tbl
ORDER BY 1, 2 DESC, 3;
числа относятся к порядковым позициям в SELECT список. Вы можете записать имена столбцов для ясности:
SELECT DISTINCT ON (id)
id, count, year
FROM tbl
ORDER BY id, count DESC, year;
результат упорядочивается по id, что может быть или не может быть приветствуется. В любом случае, это лучше, чем "неопределенный".
он также ломает связи (когда несколько лет имеют одинаковое максимальное количество) четко определенным образом: выберите самый ранний год. Если вам все равно, бросьте year С ORDER BY. Или выберите последний год с year DESC.
больше объяснений, ссылок, эталона и, возможно, более быстрых решений в этом тесно связанном ответе:
в сторону: в запросе реальной жизни вы не будете использовать некоторые имена столбцов. id является не описательным анти-шаблоном для имени столбца,count это зарезервированное слово в стандартном SQL и агрегатная функция в Postgres.