计算移动窗口中的字符串值

时间:2015-02-22 19:16:52

标签: sql postgresql window-functions

我正在尝试计算移动窗口中字符串值的出现次数。具体来说,我想计算前3行的每个字符串值的出现次数 - 不包括行

我的数据看起来像这样:

id |  color
---+---------
 0 |  'blue'
 : |      :
 6 | 'green'
 7 |  'blue'
 8 | 'green'
 9 |   'red'
10 |   'red'

我想尝试这样的事情:

id | n_red | n_blue | n_green 
---+-------+--------+---------
 : |     : |      : |       :
 9 |     0 |      1 |       2
10 |     1 |      1 |       1

其中数据是之前 3行中每个“红色”,“蓝色”和“绿色”的出现次数(例如,在id 10之前的3行中有1个红色, 1蓝色,1绿色。

我想我应该可以使用窗口函数来完成这项工作,但还是无法完成它。

select
    sum(red) over(order by id rows between 3 preceding and 1 preceding) end as n_red,
    sum(blue) over(order by id rows between 3 preceding and 1 preceding) end as n_blue,
    sum(green) over(order by id rows between 3 preceding and 1 preceding) end as n_green
from (select id,
        case when color = 'red' then 1 else 0 end as red,
        case when color = 'blue' then 1 else 0 end as blue,
        case when color = 'green' then 1 else 0 end as green
    from color_table) as dummy_color_table

这似乎有效,但并不是非常简约。有没有人有编写这些类型的查询的经验,谁可以改进它?

1 个答案:

答案 0 :(得分:4)

您可以利用Postgres中的::

select sum((color = 'red')::int) over (order by id rows between 3 preceding and 1 preceding) end as n_red,
       sum((color = 'blue')::int) over (order by id rows between 3 preceding and 1 preceding) end as n_blue,
       sum((color = 'green')::int) over (order by id rows between 3 preceding and 1 preceding) end as n_green
from color_table;