вернуть первые три результата каждой группы (еженедельные топ-3) в Postgresql - PullRequest
0 голосов
/ 12 октября 2011
 CREATE TABLE games
    (
      idg serial NOT NULL,
      nation character(3),
      points integer,
      datag date,
      CONSTRAINT pk_games PRIMARY KEY (idg )
)

idg    nation  points      dateg
1      ita      12      2011-10-10
2      fra       9      2011-10-11
3      ita       4      2011-10-12
4      fra       8      2011-10-11
5      ger      12      2011-10-12
6      aut       6      2011-10-10
7      ita      11      2011-10-17
8      ita      10      2011-10-18
9      fra       9      2011-10-19
10     ger      15      2011-10-19
11     fra      16      2011-10-18

Я хочу отобразить три самые большие суммы, сгруппированные по неделям. Я понимаю, что не могу использовать max (sum (points)), поэтому я сделал следующий запрос:

select extract(week from datag) as "dateg", nation, sum(points) as "total"
from games
group by dateg, nation
order by dateg asc, total desc limit 3

но это возвращает мне только первые три итога. Как я могу сделать это за каждую неделю (первые три итога по каждой группе, это будет своего рода «еженедельная тройка»)? Любая идея?

Работа в Postgresql 9.

Заранее спасибо.

1 Ответ

5 голосов
/ 12 октября 2011

Использовать оконную функцию :

select idg, nation, points, wk, r
from (
    select idg, nation, points, extract(week from datag) as wk,
           row_number() over (partition by extract(week from datag) order by points desc) as r
    from games
) as dt
where r <= 3

Настройте SELECT по своему усмотрению. Вы можете добавить nation к ORDER BY внутри PARTITION, если хотите получить уникальный рейтинг.

И если вы хотите сначала подсчитать количество недельных баллов для каждой страны, просто добавьте еще одну производную таблицу и немного подкорректируйте названия столбцов:

select nation, wk, wk_points, rn
from (
    select nation, wk, wk_points,
           row_number() over (partition by wk order by wk_points desc) as rn
    from (
        select nation, extract(week from datag) wk, sum(points) wk_points
        from games
        group by wk, nation
    ) as dt_sum
) as dt
where rn <= 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...