试图在Postgresql 9.3

时间:2015-08-18 18:40:11

标签: json postgresql postgresql-9.3

我正在尝试查询一个带有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)。

ref1:http://sqlfiddle.com/#!15/5febb/1

ref2:How to query an array of JSON in PostgreSQL 9.3?

1 个答案:

答案 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)