递归跟踪状态数未知的客户的状态(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;