Question

I have the following set of data:

 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

Given two time ranges:

  1. 02-01-2014..02-03-2014
  2. 02-04-2014..02-06-2014

I need to get average score for each player within a given time range. Ultimate result I'm trying to achieve is this:

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

The original algorithm I came up with was:

  1. perform SELECT with two values, derived by partitioning the set of scores into two for each time period
  2. over the first SELECT, perform another one, grouping the set by player name.

I'm stuck on step 1: running the following query:

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;

Gets me incorrect result (note how period1 and period2 average scores scores are the same:

 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

I think I don't fully understand how window functions work... I have 2 questions:

  1. What is wrong with my query?
  2. How do I do it right?
Was it helpful?

Solution

You don't need window function for this. Try:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top