查询SQL中的行序列

nic*_*ten 8 regex sql

假设我在表中存储events关联,users如下所示(dt代表事件的时间戳):

| dt | user | event |
|  1 |  1   |   A   |
|  2 |  1   |   D   |
|  3 |  1   |   B   |
|  4 |  1   |   C   |
|  5 |  1   |   B   |
|  6 |  2   |   B   |
|  7 |  2   |   B   |
|  8 |  2   |   A   |
|  9 |  2   |   A   |
| 10 |  2   |   C   |
Run Code Online (Sandbox Code Playgroud)

这样我们可以说:

  • 用户1具有ADBCB的事件序列
  • 用户2具有事件序列BBAAC

我想要回答的有关这些用户的问题类型很容易表达为对事件序列的常规表达,例如"哪些用户有事件序列匹配A.*B?" 或"哪些用户的事件序列匹配A [^ C]*B [^ C]*D?" 等等

什么是一个很好的SQL技术或运算符,我可以用来回答这个表结构上的类似查询?

有没有一种方法能够有效地/动态生成的表格user至- event-sequence它然后可以用正则表达式查询?

我目前正在使用Postgres,但我很想知道是否有任何像SQLServer或Oracle这样的大型DBMS也有专门的运算符.

a_h*_*ame 5

使用Postgres 9.x这实际上非常简单:

select userid, 
       string_agg(event, '' order by dt) as event_sequence
from events
group by userid;
Run Code Online (Sandbox Code Playgroud)

使用该结果,您现在可以在event_sequence上应用正则表达式:

select * 
from (
  select userid, 
         string_agg(event, '' order by dt) as event_sequence
  from events
  group by userid
) t
where event_sequence ~ 'A.*B'
Run Code Online (Sandbox Code Playgroud)

使用Postgres 8.x,您需要找到string_agg()函数的替代品(只是google for it,有很多例子),你需要一个子选择来确保聚合的排序为8.x确实支持order by聚合函数.