我们将状态转换数据存储在json列中,如下所示:
state: {
current_state: 'state_three',
transitions: [
{ from: 'state_two', to: 'state_three', at: [time in iso8601] },
{ from: 'state_one', to: 'state_two', at: [time in iso8601] }
]
}
有时我们需要在一段时间之前查询处于某种状态的行,因此我们有一个如下所示的查询:
SELECT *
FROM my_table, json_array_elements("my_table"."state"->'transitions') as state_changes
WHERE ((state_changes->>'to' = 'state_two')
AND (state_changes->>'at' < '2016-04-11 00:00:00.000000'))
此查询的问题在于,在某些情况下,我们可能会多次转换到相关状态(state_two
):
state: {
current_state: 'state_two',
transitions: [
{ from: 'state_two', to: 'state_one', at: [time in iso8601] },
{ from: 'state_one', to: 'state_two', at: [time in iso8601] },
{ from: 'state_two', to: 'state_one', at: [time in iso8601] },
{ from: 'state_one', to: 'state_two', at: [time in iso8601] }
]
}
在这种情况下,当WHERE
子句与多个transitions
数组元素匹配时,查询将多次返回同一行。是否有另一种方法来构造此查询,以便所有匹配的行只返回一次?
答案 0 :(得分:0)
像(未经测试)的东西:
SELECT *
FROM my_table
WHERE EXISTS (
SELECT 1
FROM json_array_elements(state->'transitions') state_changes(v)
WHERE (
(v->>'to' = 'state_two') AND
(v->>'at' < '2016-04-11 00:00:00.000000'))
)
提示:如果要在SQL查询中使用其元素,请不要使用JSON数据类型。改为使用表格/列。