表架构:
create table test_table
(
id serial not null,
data jsonb
);
示例数据:
INSERT INTO public.test_table (id, data) VALUES (1, '[{"": "VALUE1", "KEY2": "VALUE2"}, {"KEY1": "VALUE3", "KEY3": "VALUE4"}]');
INSERT INTO public.test_table (id, data) VALUES (2, '[{"''KEY1 ''": "VALUE1", "KEY2": "VALUE2"}, {"KEY3": "VALUE3", "KEY4": "VALUE4"}]');
SQL查询:
SELECT id, arr_elem
FROM test_table AS tt, jsonb_array_elements(
(
SELECT data
FROM test_table
WHERE id = tt.id
)
) AS arr_elem
WHERE arr_elem#>'{KEY1}' IS NOT NULL
我想调整到上面的查询以匹配以下场景:
"": "VALUE1"
"''": "VALUE1"
"'KEY1 '": "VALUE1"
试图逃避引号和空格,查询没有返回预期的结果。
更新1:
解决方案1: http://sqlfiddle.com/#!17/6d431/20
SELECT id, arr_elem
FROM test_table AS tt, jsonb_array_elements(
(
SELECT data
FROM test_table
WHERE id = tt.id
)
) AS arr_elem
WHERE arr_elem->'' IS NOT NULL
答案 0 :(得分:1)
select * from test_table
where data->'' is not null /*gets rows with blank key names;
select * from test_table
where data->'''''' is not null; /*gets rows with '' as a key name;
最后一点有点复杂......
select * from test_table
where exists
(select * from json_each(data) where key != rtrim(key))
过去的那一行得到任何键!= rtrim(key)的行,所以应该得到键名中有尾随空格的项。
答案 1 :(得分:0)
另一个答案更适合您拥有的json“对象数组”:
select * from test_table
where exists
(select * from jsonb_array_elements(data)
where exists
(select * from
(select jsonb_object_keys as k from
jsonb_object_keys(jsonb_array_elements)
) x
where x.k ='' or x.k ='''''' or x.k like '% '''
)
);
注意:最里面的部分(将json_object_keys选择为k ...)在语法上实际上不是必需的,但我永远无法使它作为较小的“一个衬里”起作用。
此外,此查询一次选择所有3个条件。您可以通过调整where子句的3个“或”部分轻松地调整它以清除这些情况,或者一次执行一次。
说明:您必须先使用jsonb_array_elements将数据列扩展为对象数组,以获取每个对象,然后将每个对象扩展为键数组,然后可以按以下方式搜索普通文字。