1

次の表があります。

CREATE TABLE mytable (
  id       serial PRIMARY KEY
, employee text UNIQUE NOT NULL
, data     jsonb
);

次のデータを使用します。

INSERT INTO mytable (employee, data)
VALUES
 ('Jim', '{"sales_tv": [{"value": 10, "yr": "2010", "loc": "us"}, {"value": 5, "yr": "2011", "loc": "europe"}, {"value": 40, "yr": "2012", "loc": "asia"}], "sales_radio": [{"value": 11, "yr": "2010", "loc": "us"}, {"value": 8, "yr": "2011", "loc": "china"}, {"value": 76, "yr": "2012", "loc": "us"}], "another_key": "another value"}'),
 ('Rob', '{"sales_radio": [{"value": 7, "yr": "2014", "loc": "japan"}, {"value": 3, "yr": "2009", "loc": "us"}, {"value": 37, "yr": "2011", "loc": "us"}], "sales_tv": [{"value": 4, "yr": "2010", "loc": "us"}, {"value": 18, "yr": "2011", "loc": "europe"}, {"value": 28, "yr": "2012", "loc": "asia"}], "another_key": "another value"}')

「sales_tv」と「sales_radio」以外にもキーがあることに注意してください。以下のクエリでは、「sales_tv」と「sales_radio」に注目する必要があります。

「sales_」で始まるオブジェクトのリストをジムに返そうとしています。リスト内の各オブジェクトで、値と年を返す必要があります(「場所」またはその他のキーは無視します)例:

    employee |  sales_
    Jim      |  {"sales_tv": [{"value": 10, "yr": "2010"}, {"value": 5, "yr": "2011"}, {"value": 40, "yr": "2012"}],
                 "sales_radio": [{"value": 11, "yr": "2010"}, {"value": 8, "yr": "2011"}, {"value": 76, "yr": "2012"}]}

各値を取得できますが、年もリスト形式も必要ありません。

SELECT t.employee, json_object_agg(a.k, d.value) AS sales
FROM   mytable t
     , jsonb_each(t.data)      a(k,v) 
     , jsonb_to_recordset(a.v) d(yr text, value float)
WHERE  t.employee = 'Jim'
AND    a.k LIKE 'sales_%'
GROUP  BY 1

結果:

employee    | sales
----------  | --------
Jim         | { "sales_tv" : 10, "sales_tv" : 5, "sales_tv" : 40, "sales_radio" : 11, "sales_radio" : 8, "sales_radio" : 76 }
4

1 に答える 1

0

原則は、あなたが昨日尋ねた質問、最初のクエリと同じです (この質問は昨日の 2 番目のクエリですが): データ内の階層のレイヤーを剥がしてからjson、関心のあるデータを使用して再構築します。新しいjsonフォーマット。

SELECT employee, json_object_agg(k, jarr) AS sales
FROM (
  SELECT t.employee, a.k,
         json_agg(json_build_object('value', d.value, 'yr', d.yr)) AS jarr
  FROM mytable t,
       jsonb_each(t.data) a(k, v),
       jsonb_to_recordset(a.v) d(yr text, value float)
  WHERE t.employee = 'Jim'
    AND a.k like 'sales_%'
  GROUP BY 1, 2) sub
GROUP BY 1; 

この節では、 や などFROMの関数を使用して JSON 階層を分解します。最後の関数の名前がす​​でに示しているように、これらの関数はそれぞれ、他のテーブルとその列と同じように操作できる一連のレコードを生成します。列選択リストで、必要なデータと適切な集計関数を選択し、JSON の結果をつなぎ合わせます。階層のすべてのレベルに対して、1 つの集約関数が必要であり、したがって 1 つのレベルのサブクエリが必要です。jsonb_eachjsonb_to_recordsetjson_aggjson_object_agg

于 2015-07-23T08:23:19.127 に答える