我正在尝试查询一个带有JSON列的表,该列始终包含一个“原始”值数组(即整数,字符串,布尔值 - 而不是对象或数组)。
我的查询应该类似于[ref2],但是我不能->>'id'
,因为我不是试图访问JSON对象而是访问值本身。
在[ref1]小提琴(上面的明显分叉)中,有不完整的查询... 我想查询其值中包含things
的所有3
< / em>的
更重要的是,我希望有些行可以有字符串数组,其他行有整数数组,而其他行有布尔数组......所以转换是不可思议的。
我相信->>
会返回原始的JSON值类型,但我需要“root”对象...也就是说,我的JSON值为[1,2,3,4]
,使用json_array_elements
应该会产生2
,但根据我的测试,这是一种JSON类型。
计划在不久的将来升级到9.4,但我还没有读过任何能给我一些线索的信息jsonb
会对我有所帮助。
更新:此刻,我(1)确保所有值都是整数(将非整数值映射到整数),这是次优的; (2)这样查询:
SELECT *
FROM things, json_array_elements(things.values) AS vals
WHERE vals.value::text::integer IN (1,2,3);
我需要双重投射(否则它会抱怨cannot cast type json to integer
)。
答案 0 :(得分:1)
使用json_array_elements
运算符提取文本表示,而不是使用generate_series
,您可以使用->>
解包数组。
SELECT things.*
FROM things
CROSS JOIN generate_series(0, json_array_length(values) - 1) AS idx
WHERE values ->> idx = '1'
GROUP BY things.id;
这是9.3中缺少json_array_elements_text
的解决方法。
json需要operator(=)
才能执行此操作,而不必使用强制转换或依赖于整数,布尔值等的特定文本表示。operator(=)
仅适用于jsonb
。因此,在9.3中,您仍然坚持使用文本表示(因此1.00
赢得=
1
)或根据元素类型转换为PostgreSQL类型。< / p>
在9.4中你可以使用to_json
和jsonb operator(=)
,例如:
SELECT things.*
FROM things
CROSS JOIN generate_series(0, json_array_length(values) - 1) AS idx
WHERE (values -> idx)::jsonb = to_json(1)::jsonb
GROUP BY things.id;
id | date | values
----+-------------------------------+---------
1 | 2015-08-09 04:54:38.541989+08 | [1,2,3]
(1 row)