2013-11-09 1 views
1

Мне нравится знать, как я могу разделить окно на фиксированное количество записей.Перегородка по фиксированному числу записей

Пример (http://sqlfiddle.com/#!1/7df86).

CREATE TABLE Games 
(
id serial primary key, 
game_no integer not null, 
points integer, 
    constraint game_no unique (game_no) 
); 

INSERT INTO Games (game_no, points) 
VALUES (3123, 5), (3126, 5), (3135, 8), (3128, null), (3130, 1), (3121, 11), 
(3132, 0), (3133, 4), (3110, 7), (3112, null), (3113, 12), (3125, 3),(3134, 8); 

Я хочу, чтобы сумма очков трех игр вместе взятых, начиная с наибольшим количеством игр, по убыванию упорядоченного по количеству игр. Как это.

| GAME_NO | POINTS | SUM_THREE | 
|---------|--------|-----------| 
| 3135 |  8 |  20 | 
| 3134 |  8 |  20 | 
| 3133 |  4 |  20 | 
| 3132 |  0 |   1 | 
| 3130 |  1 |   1 | 
| 3128 | (null) |   1 | 
| 3126 |  5 |  13 | 
| 3125 |  3 |  13 | 
| 3123 |  5 |  13 | 
| 3121 |  11 |  23 | 
| 3113 |  12 |  23 | 
| 3112 | (null) |  23 | 
| 3110 |  7 |   7 | 

Как это сделать с помощью функции окна без использования подзапроса? Я также не могу использовать, например, оператор with. Он должен быть одним единственным запросом из-за внешнего анализатора, который его выполнит (и у меня нет контроля). Кажется, это так просто, и я ломаю голову над ним последние пару дней :)

ответ

0

Вы можете использовать функцию row_number, деленную на 3, чтобы присвоить уникальный номер каждой группе из трех последовательных строк. Затем используйте сумму как аналитическую функцию для каждой группы.

SQL Fiddle

with x(game_no, points, grp) as (
    select game_no, points, 
     ceil(cast(row_number() over (order by game_no desc) as decimal)/ 3) 
    from games 
) 
select game_no, points, 
     sum(points) over (partition by grp) 
from x 
order by game_no desc; 

Вы можете использовать встроенный вид вместо с конструкцией.

select game_no, points, 
     sum(points) over (partition by grp) 
from (
     select game_no, points, 
      ceil(cast(row_number() over 
        (order by game_no desc) as decimal)/ 3) as grp 
     from games 
    ) as x 
order by game_no desc; 

Results:

| GAME_NO | POINTS | SUM | 
|---------|--------|-----| 
| 3135 |  8 | 20 | 
| 3134 |  8 | 20 | 
| 3133 |  4 | 20 | 
| 3132 |  0 | 1 | 
| 3130 |  1 | 1 | 
| 3128 | (null) | 1 | 
| 3126 |  5 | 13 | 
| 3125 |  3 | 13 | 
| 3123 |  5 | 13 | 
| 3121 |  11 | 23 | 
| 3113 |  12 | 23 | 
| 3112 | (null) | 23 | 
| 3110 |  7 | 7 | 
+0

Как вы думаете, можно добиться того же результата, не используя 'с' строительство? Я отредактирую свой пост, чтобы сделать его более понятным. Мне нужно решение «одного заявления». –

+0

@JaneDoe, Обновлен ответ. – Noel

+1

Парсер действительно принимает встроенный вид. И я многому научился из ваших запросов :) Спасибо. –