我的JSON列中的一行看起来像这样:
{"general": {
"somekey": "somevalue",
"tags": ["first_tag", "second_tag", "third_tag"]}}
我需要返回包含某些标签的标签列表(例如“first_tag”)。有没有办法在PostgreSQL 9.3中执行此操作?
答案 0 :(得分:1)
假设该表名为t
且该列名为x
:
SELECT *
FROM t
WHERE exists(
SELECT 1
FROM json_array_elements(x#>'{general,tags}')
WHERE array_to_json(array[value])->>0='first_tag'
);
这不使用jsonb
或其他更新的东西,因此它应该适用于9.3。另请参阅sqlfiddle。
这个想法是使用json_array_elements
函数,它将json数组转换为sql表。该表有一个名为value
的{{1}}类列。
在这种情况下,我们在子查询中使用json
来遍历所有标记的列表。一个复杂因素是json_array_elements
(此处表示标记)的类型为value
,因此我们必须将其转换为文本。不幸的是,json
没有直接执行此操作的功能,因此我们必须将其转换为单个元素数组,然后将该单个元素作为文本提取。然后我们可以将该文本与我们要查找的标记进行比较(在上例中为postgresql
)。这一栏的结果并不重要,我们只关心它是否为空。
答案 1 :(得分:0)
您可以使用:
CREATE OR REPLACE FUNCTION fn_json_array_contains(a_json json, a_e anyelement)
RETURNS BOOLEAN AS $BODY$
BEGIN
RETURN to_json(a_e)::TEXT IN (SELECT value::TEXT FROM json_array_elements(a_json) e);
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE
;
SELECT * FROM t WHERE fn_json_array_contains(x#>'{general,tags}', 'first_tag');