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
этого конкретного года.
Итак, как я могу написать этот запрос? Я хочу получить id
s 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.