我有一个状态机架构,其中一个记录将有许多状态转换,一个具有最大sort_key
列的记录是当前状态。我的问题是确定哪些记录在给定日期内保持特定状态(或状态)。
示例数据:
items table
id
1
item_transitions table
id item_id created_at to_state sort_key
1 1 05/10 "state_a" 1
2 1 05/12 "state_b" 2
3 1 05/15 "state_a" 3
4 1 05/16 "state_b" 4
问题:
确定来自items
表的所有记录,其在05/15日期持有状态“state_a”。这应该显然返回示例数据中的项目,但如果您使用日期“05/16”查询,则不应该。
我认为我将使用LEFT OUTER JOIN
将items_transitions表连接到自身并缩小可能性,直到我有什么要查询的内容,这将为我提供所需的项目。也许我忽视了一些更为简单的事情。
答案 0 :(得分:1)
你的问题改写意味着"给我所有在05/15或之前已经改变为state_a的项目,之后没有改变到另一个州。请注意,对于该示例,它将2001年添加为获得有效日期的年份。如果你的" created_at"列不是日期时间我强烈建议更改它。
首先,您可以在阈值日期之前检索所有项目的最后一个sort_key:
SELECT item_id,max(sort_key) last_change_sort_key
FROM item_transistions it
WHERE created_at<='05/15/2001'
GROUP BY item_id
下一步是将此结果连接回item_transitions表,以查看在此特定sort_key上切换项目的状态:
SELECT *
FROM item_transistions it
JOIN (SELECT item_id,max(sort_key) last_change_sort_key
FROM item_transistions it
WHERE created_at<='05/15/2001'
GROUP BY item_id) tmp ON it.item_id=tmp.item_id AND it.sort_key=tmp.last_change_sort_key
最后,你只想要那些切换到“状态”的人。所以只需添加一个条件:
SELECT DISTINCT it.item_id
FROM item_transistions it
JOIN (SELECT item_id,max(sort_key) last_change_sort_key
FROM item_transistions it
WHERE created_at<='05/15/2001'
GROUP BY item_id) tmp ON it.item_id=tmp.item_id AND it.sort_key=tmp.last_change_sort_key
WHERE it.to_state='state_a'
您没有提到您使用的DBMS,但我认为此查询应该与最常见的一起使用。