查询 Postgres 9.3 JSON 以检查数组是否包含字符串?
Query Postgres 9.3 JSON to check if array contains a string?
我的 JSON 列中的一行看起来像这样:
{"general": {
"somekey": "somevalue",
"tags": ["first_tag", "second_tag", "third_tag"]}}
我需要 return 包含特定标签的标签列表行(例如 "first_tag")。有没有办法在 PostgreSQL 9.3 中执行此操作?
假设 table 被称为 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 table。 table 有一个名为 value
的列,类型为 json
。
在这种情况下,我们在子查询中使用 json_array_elements
来遍历所有标签的列表。一个复杂的问题是 value
(这里代表一个标签)是 json
类型,因此我们必须将其转换为文本。不幸的是,postgresql
没有直接执行此操作的函数,因此我们必须将其转换为单个元素数组,然后将该单个元素提取为文本。然后我们可以将该文本与我们要查找的标签(上例中的 first_tag
)进行比较。这一列的结果并不重要,我们只关心它是否为空。
您可以使用:
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');
我的 JSON 列中的一行看起来像这样:
{"general": {
"somekey": "somevalue",
"tags": ["first_tag", "second_tag", "third_tag"]}}
我需要 return 包含特定标签的标签列表行(例如 "first_tag")。有没有办法在 PostgreSQL 9.3 中执行此操作?
假设 table 被称为 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 table。 table 有一个名为 value
的列,类型为 json
。
在这种情况下,我们在子查询中使用 json_array_elements
来遍历所有标签的列表。一个复杂的问题是 value
(这里代表一个标签)是 json
类型,因此我们必须将其转换为文本。不幸的是,postgresql
没有直接执行此操作的函数,因此我们必须将其转换为单个元素数组,然后将该单个元素提取为文本。然后我们可以将该文本与我们要查找的标签(上例中的 first_tag
)进行比较。这一列的结果并不重要,我们只关心它是否为空。
您可以使用:
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');