递归跟踪状态数未知的客户的状态(Presto SQL)

递归跟踪状态数未知的客户的状态(Presto SQL),sql,amazon-athena,presto,Sql,Amazon Athena,Presto,我有一个表,其中包含客户的当前状态id,另一个表包含所有状态及其状态id,但没有相应的客户id 但是,历史状态表保存它所替换的state\u id的信息。因此,应该可以递归地跟踪客户的状态/旅程 考虑以下示例: “客户”表: “历史状态”表: 我有兴趣获得每个客户的历史状态信息,即下表: customer_id state_created state_name 1 2015-10-00 State1 1

我有一个表,其中包含客户的当前
状态id
,另一个表包含所有状态及其
状态id
,但没有相应的
客户id

但是,历史状态表保存它所替换的
state\u id
的信息。因此,应该可以递归地跟踪客户的状态/旅程

考虑以下示例:

“客户”表:

“历史状态”表:

我有兴趣获得每个客户的历史状态信息,即下表:

customer_id    state_created      state_name       
1              2015-10-00         State1
1              2017-11-09         State5
2              2017-06-28         State1
2              2017-12-13         State6
2              2018-04-01         State4
3              2018-07-10         State3
因此,对于任何
客户id
我都知道
当前状态id
。有了这个
state\u id
我可以用
replace\u state\u id
递归地跟踪给定客户所处的所有状态

我想要一个表格,显示历史上所有客户和这些客户所在的所有州(创建
state\u
列)。没有明确给出每个客户所处的状态数


数据放在AWS的Athena中,因此应使用presto sql作为语言。

在此处尝试使用递归CTE:

WITH RECURSIVE cte (state_id, state_name, state_created) AS (
    SELECT state_id, state_name, state_created
    FROM Historical_state
    UNION ALL
    SELECT h1.state_id, h2.state_name, h2.state_created
    FROM Historical_state h1
    INNER JOIN cte h2
        ON h1.replace_state_id = h2.state_id
)

SELECT
    c.customer_id,
    t.state_created,
    t.state_name
FROM Customer c
INNER JOIN cte t
    ON c.current_state_id = t.state_id
ORDER BY
    c.customer_id,
    t.state_created;

同样,正如中的情况一样,我不能展示SQLite的Rextester演示,它不支持SQL方言。但是,下面的演示显示递归CTE逻辑实际上在SQL Server上工作


否您以前的解决方案导致customer_id=2出现两种历史状态。也就是说,它只显示customer_id two处于State6和State4,但缺少State1。类似地,如果一个客户历史上曾处于4个状态,比如State1 State2、State3和State4,那么您的代码只说明该客户最近的两个状态。我现在看到了。这里需要使用递归查询。显然,雅典娜不支持递归查询。通过ODBC将MySQL Workbench连接到Athena也不是一个解决方案,因为我是只读访问,这使得我无法进行递归查询。这个问题还有其他解决方法吗?@NicolaiIversen您不需要递归CTE本身;正如我昨天的回答所做的那样,您可以只做覆盖整个链所需的许多自联接。但是,如果你不知道这个数字,那么问题就变得困难了。我给出的答案是在大多数数据库上执行此操作的首选方法。我也这么认为。谢谢你的帮助:)
customer_id    state_created      state_name       
1              2015-10-00         State1
1              2017-11-09         State5
2              2017-06-28         State1
2              2017-12-13         State6
2              2018-04-01         State4
3              2018-07-10         State3
WITH RECURSIVE cte (state_id, state_name, state_created) AS (
    SELECT state_id, state_name, state_created
    FROM Historical_state
    UNION ALL
    SELECT h1.state_id, h2.state_name, h2.state_created
    FROM Historical_state h1
    INNER JOIN cte h2
        ON h1.replace_state_id = h2.state_id
)

SELECT
    c.customer_id,
    t.state_created,
    t.state_name
FROM Customer c
INNER JOIN cte t
    ON c.current_state_id = t.state_id
ORDER BY
    c.customer_id,
    t.state_created;