【问题标题】:Partition by fixed number of records按固定数量的记录分区
【发布时间】:2013-11-21 09:39:45
【问题描述】:

我想知道如何按固定数量的记录对窗口进行分区。

示例 (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 语句。它必须是一个查询,因为外部解析器将执行它(我无法控制)。看起来很简单,最近几天我都在琢磨它:)

【问题讨论】:

    标签: sql postgresql window-functions postgresql-9.0


    【解决方案1】:

    您可以使用 row_number 函数除以 3 为每组 3 个连续行分配唯一编号。然后使用 sum 作为每个组的解析函数。

    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;
    

    您可以使用内联视图代替 with 构造。

    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 |
    

    【讨论】:

    • 你认为不使用'with'结构也能达到同样的效果吗?我将编辑我的帖子以更清楚地说明我需要一个“单一声明”的解决方案。
    • @JaneDoe,更新了答案。
    • 解析器确实接受内联视图。我从您的查询中学到了很多东西:)谢谢。
    • 我发现这个查询效率很低——可以用索引加速吗?
    • 我发现内联视图非常有用。在我的组织中为每个部门添加了一个属性来执行此计算:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-18
    • 2016-11-13
    • 1970-01-01
    • 2020-03-29
    • 2021-12-21
    相关资源
    最近更新 更多