如何在SQL中按信号分割事件序列?

时间:2014-05-23 05:34:33

标签: sql

我有一个包含两个字段'order'和'events'的表,有两种类型的事件'C'和'S',我希望能够在信号事件的开始时对行进行分段/分组',即添加一个列“会话”,如下所示

order  event  session
1      C      1
2      C      1
3      C      1
4      S      1
5      C      2
6      S      2
7      C      3
8      C      3
9      S      3

SQL查询可以完成这项工作吗?感谢。

1 个答案:

答案 0 :(得分:0)

这是用SQL Server语法编写的(对于示例数据的表变量),但它是相当标准的SQL,通过查看query reference,我认为它应该在BigQuery中运行(一次适应你的实际表) ):

declare @t table ([order] int, event char(1))
insert into @t([order],event) values
(1,'C'),    (2,'C'),    (3,'C'),    (4,'S'),    (5,'C'),
(6,'S'),    (7,'C'),    (8,'C'),    (9,'S')

select
    t.*,
    s1.rn
from @t t
    inner join
(
select
    *,
    ROW_NUMBER() OVER (ORDER BY [order]) as rn
from
    @t
where
    event='S'
) s1
    on
        t.[order] <= s1.[order]
    left join
(
select
    *,
    ROW_NUMBER() OVER (ORDER BY [order]) as rn
from
    @t
where
    event='S'
) s2
    on
        t.[order] <= s2.[order] and
        s2.[order] < s1.[order]
where
    s2.[order] is null

我通常会使用公用表表达式(CTE),而不是复制S值的子查询,但我看不出是否支持它。

逻辑应该相当简单 - 我们使用简单的S函数对ROW_NUMBER()行进行编号,然后我们将原始表中的每一行与S行匹配大多数人立即成功。


CTE变体(但是,就像我说的那样,我在文档中看不到对CTE的支持):

declare @t table ([order] int, event char(1))
insert into @t([order],event) values
(1,'C'),    (2,'C'),    (3,'C'),    (4,'S'),    (5,'C'),
(6,'S'),    (7,'C'),    (8,'C'),    (9,'S')

;With Numbered as (
    select
    *,
    ROW_NUMBER() OVER (ORDER BY [order]) as rn
from
    @t
where
    event='S'
)
select
    t.*,
    s1.rn
from @t t
    inner join
Numbered s1
    on
        t.[order] <= s1.[order]
    left join
Numbered s2
    on
        t.[order] <= s2.[order] and
        s2.[order] < s1.[order]
where
    s2.[order] is null