0

テーブル スキーマ:

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"

引用符とスペースをエスケープしようとしましたが、クエリは期待した結果を返しませんでした。

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

2 に答える 2

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) の行を取得するため、キー名の末尾にスペースがある項目を取得する必要があります。

于 2017-09-29T20:02:44.860 に答える
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つの「または」セクションを調整することで、これらのシナリオを除外したり、一度に1つずつ実行したりするために簡単に調整できます...

説明: 最初に jsonb_array_elements を使用してデータ列をオブジェクトの配列に展開し、各オブジェクトを取得する必要があります。次に、これらのオブジェクトのそれぞれをキーの配列に展開する必要があります。これにより、通常のテキストとして検索できます。

于 2018-09-05T19:14:27.097 に答える