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.