PostgreSQL JSONB - 如何匹配空字符串键

时间:2017-09-29 17:51:58

标签: postgresql postgresql-json

表架构:

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

我想调整到上面的查询以匹配以下场景:

  1. 找到空字符串的键:例如:"": "VALUE1"
  2. 只用单引号查找密钥:例如:"''": "VALUE1"
  3. 找到包含在单引号中的尾随空格的键:例如:"'KEY1 '": "VALUE1"
  4. 试图逃避引号和空格,查询没有返回预期的结果。

    更新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
    

2 个答案:

答案 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将数据列扩展为对象数组,以获取每个对象,然后将每个对象扩展为键数组,然后可以按以下方式搜索普通文字。