计算移动 window 中的字符串值

Count string values across moving window

我正在尝试计算移动 window 中字符串值的出现次数。具体来说,我想计算前 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

其中数据是 'red'、'blue' 和 'green' 在 previous 3 行中出现的次数(例如id 10 之前的 3 行有 1 个红色、1 个蓝色和 1 个绿色)。

我想我应该可以使用 window 函数来完成此操作,但还没有完全解决它。

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

这似乎可行,但不是很简洁。有没有人有编写这些类型的查询的经验谁可以改进它?

您可以在 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;