在 Vertica 中运行递归查询

Posted

技术标签:

【中文标题】在 Vertica 中运行递归查询【英文标题】:Running recursive query in Vertica 【发布时间】:2018-08-22 19:50:36 【问题描述】:

我正在尝试做与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
------- ---------- -------- --------- -----

【问题讨论】:

我建议您在所询问的查询中提供示例数据和所需结果,而不是依赖另一个相当复杂的问题。 @GordonLinoff 感谢您的评论。我已经更新了问题。 什么是“vertica”,它与 Oracle 有什么关系? (或者——是吗?)Oracle SQL 解决方案有帮助吗?如果没有,您问题底部的oracle 标签可能应该被删除。 @mathguy Vertica 是一个柱状 RDBMS。我不确定 Oracle SQL 解决方案是否有帮助,因此我保留了这些标签,以便有这方面专业知识的人可以帮助我。 好的,看来(通过快速谷歌搜索)vertica 支持分析功能,我认为它应该支持子查询...我将发布一个 Oracle 解决方案,看看它是否有帮助。 【参考方案1】:

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

这里使用的方法是一个非常有名的方法,它通常被称为“start-of-groups”方法(用于在最里面的子查询中创建的“标志”)。

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
;

【讨论】:

此时我可以访问我的数据子集,您的工作代码就像一个魅力。明天早上我将在完整的数据集上运行它并让你知道。但我看不出为什么它不会。非常感谢您。 您的代码运行良好。我可以在这里问另一个问题来代替上述问题吗? @FightMilk - 你可以问另一个问题;但如果和上面的不一样,你应该开一个新线程。 谢谢。会这样做的!

以上是关于在 Vertica 中运行递归查询的主要内容,如果未能解决你的问题,请参考以下文章

从递归查询错误中查看

MySQL怎样做递归查询

Oracle SQL 分析查询 - 类似电子表格的递归运行总计

SQL递归查询知多少

从多个 OU 中递归查询用户的 LDAP 角色

sqlite3-树形递归查询-with