奇怪的窗口函数行为

时间:2014-02-14 23:19:27

标签: sql postgresql window-functions

我有以下数据集:

 player | score |        day   
--------+-------+------------
   John |     3 | 02-01-2014
   John |     5 | 02-02-2014
   John |     7 | 02-03-2014
   John |     9 | 02-04-2014
   John |    11 | 02-05-2014
   John |    13 | 02-06-2014
   Mark |     2 | 02-01-2014
   Mark |     4 | 02-02-2014
   Mark |     6 | 02-03-2014
   Mark |     8 | 02-04-2014
   Mark |    10 | 02-05-2014
   Mark |    12 | 02-06-2014

给出两个时间范围:

  1. 02-01-2014..02-03-2014
  2. 02-04-2014..02-06-2014
  3. 我需要在给定的时间范围内获得每位玩家的平均分数。我试图实现的最终结果是:

     player | period_1_score | period_2_score
    --------+----------------+----------------
       John |              5 |             11
       Mark |              4 |             10
    

    我想出的原始算法是:

    1. 使用两个值执行SELECT,这两个值是通过将每个时间段的分数分组为两个而得出的
    2. 在第一个SELECT上,执行另一个,按玩家名称对该组进行分组。
    3. 我坚持第1步:运行以下查询:

      SELECT
        player,
        AVG(score) OVER (PARTITION BY day BETWEEN '02-01-2014' AND '02-03-2014') AS period_1,
        AVG(score) OVER (PARTITION BY day BETWEEN '02-04-2014' AND '02-06-2014') AS period_2;
      

      获取错误的结果(请注意period1period2平均得分如何相同:

       player | period_1_score | period_2_score
      --------+----------------+----------------
         John |              5 |              5
         John |              5 |              5
         John |              5 |              5
         John |              5 |              5
         John |              5 |              5
         John |              5 |              5
         Mark |              4 |              4
         Mark |              4 |              4
         Mark |              4 |              4
         Mark |              4 |              4
         Mark |              4 |              4
         Mark |              4 |              4
      

      我想我并不完全理解窗口功能是如何工作的......我有两个问题:

      1. 我的查询有什么问题?
      2. 我该怎么做?

1 个答案:

答案 0 :(得分:2)

您不需要窗口功能。 尝试:

select 
player
,avg(case when day BETWEEN '02-01-2014' AND '02-03-2014' then score else null end) as period_1_score
,avg(case when day BETWEEN '02-04-2014' AND '02-06-2014' then score else null end) as period_1_score
from <your data>
group by player