在Vertica中运行递归查询

时间:2018-08-22 19:50:37

标签: sql recursive-query vertica

我正在尝试做与this question完全相同的事情。但是我在Vertica,所以找不到任何方法来执行最高答案或其他答案。因此,基本上我尝试了 connect by 和子查询 UNION ALL 方法,但我认为Vertica不支持它。

有什么方法可以在Vertica中复制解决方案?

编辑:完整问题

我正在尝试计算30天的重新入学链,这是自上次入学起30天内的重新入学序列。以下数据显示了发生事件而不是入场和出场的简化情况。事件之间的天数差异将其识别为30天再入院,连续30天再入院(Chain Len)将是单个再入院(计数)。

样本数据

CREATE TABLE dbo.Events (
    EventID INT IDENTITY(1,1) PRIMARY KEY,
    EventDate DATE NOT NULL,
    PersonID INT NOT NULL
);
GO
INSERT dbo.Events (EventDate, PersonID)
VALUES 
    ('2014-01-01', 1), ('2014-01-05', 1), ('2014-02-02', 1), ('2014-03-30', 1), ('2014-04-04', 1), 
    ('2014-01-11', 2), ('2014-02-02', 2),
    ('2014-01-03', 3), ('2014-03-03', 3);
GO

样本输出

EventID EventDate  PersonID CHAIN LEN Count
------- ---------- -------- --------- -----
1       2014-01-01 1        1         1
2       2014-01-05 1        2         1
3       2014-02-02 1        3         1
------- ---------- -------- --------- -----
4       2014-03-30 1        1         2
5       2014-04-04 1        2         2
------- ---------- -------- --------- -----
6       2014-01-11 2        1         1
7       2014-02-02 2        2         1
------- ---------- -------- --------- -----
8       2014-01-03 3        1         1
------- ---------- -------- --------- -----
9       2014-03-03 3        1         2
------- ---------- -------- --------- -----

1 个答案:

答案 0 :(得分:1)

这是Oracle解决方案;看看是否有效。您可能需要对Vertica进行一些更改,因为每个数据库方言都有其自己的怪癖。 Vertica确实支持分析功能,这是主要成分。

这里使用的方法是一个众所周知的方法,通常称为“组开始”方法(用于在最里面的子查询中创建的“标志”)。

select eventid, eventdate, personid,
       row_number() over 
         (partition by personid, ct order by eventdate) as chain_len,
       ct
from   (
         select eventid, eventdate, personid,
                count(flag) over 
                  (partition by personid order by eventdate) + 1 as ct
         from   (
                  select eventid, eventdate, personid,
                         case when eventdate > lag(eventdate) over 
                              (partition by personid order by eventdate) + 30  
                              then 0 end as flag
                  from   events
                )
       )
order by personid, eventdate  -- if needed
;