sql >> Databáze >  >> RDS >> PostgreSQL

Jak mohu sloučit záznamy uvnitř dvou polí JSON?

Za předpokladu datový typ jsonb a že chcete sloučit záznamy každého pole JSON, které sdílí stejnou hodnotu 'id'.

Postgres 9.5

zjednodušuje to pomocí nového řetězení operátor || pro jsonb hodnoty :

SELECT json_agg(elem1 || elem2) AS result
FROM  (
   SELECT elem1->>'id' AS id, elem1
   FROM  (
      SELECT '[
        {"id":1, "percent":12.50}, 
        {"id":2, "percent":75.00}, 
        {"id":3, "percent":12.50}
       ]'::jsonb AS js
      ) t, jsonb_array_elements(t.js) elem1
   ) t1
FULL JOIN (
   SELECT elem2->>'id' AS id, elem2
   FROM  (
      SELECT '[
        {"id": 1, "a": "text1a", "b": "text1b", "percent":12.50},
        {"id": 2, "a": "text2a", "b": "text2b", "percent":75.00},
        {"id": 3, "a": "text3a", "b": "text3b", "percent":12.50}]'::jsonb AS js
      ) t, jsonb_array_elements(t.js) elem2
   ) t2 USING (id);

FULL [OUTER] JOIN zajišťuje, že neztratíte záznamy bez shody v druhém poli.

Typ jsonb má pohodlnou vlastnost zachovat pouze nejnovější hodnotu pro každý klíč v záznamu. Proto je duplicitní klíč 'id' ve výsledku sloučen automaticky.

Manuál Postgres 9.5 také radí:

Postgres 9.4

Je to trochu méně pohodlné. Můj nápad by byl extrahovat prvky pole a poté extrahovat všechny páry klíč/hodnota, UNION oba výsledky agregovat do jednoho nového jsonb hodnoty na hodnotu id a nakonec agregovat do jednoho pole.

SELECT json_agg(j) -- ::jsonb
FROM  (
   SELECT json_object_agg(key, value)::jsonb AS j
   FROM  (
      SELECT elem->>'id' AS id, x.*
      FROM  (
         SELECT '[
           {"id":1, "percent":12.50}, 
           {"id":2, "percent":75.00}, 
           {"id":3, "percent":12.50}]'::jsonb AS js
         ) t, jsonb_array_elements(t.js) elem, jsonb_each(elem) x
      UNION ALL  -- or UNION, see below
      SELECT elem->>'id' AS id, x.*
      FROM  (
         SELECT '[
           {"id": 1, "a": "text1a", "b": "text1b", "percent":12.50},
           {"id": 2, "a": "text2a", "b": "text2b", "percent":75.00},
           {"id": 3, "a": "text3a", "b": "text3b", "percent":12.50}]'::jsonb AS js
         ) t, jsonb_array_elements(t.js) elem, jsonb_each(elem) x
      ) t
   GROUP  BY id
   ) t;

Odeslání do jsonb odstraní duplicitní klíče. Alternativně můžete použít UNION pro skládání duplikátů (například pokud chcete json jako výsledek). Vyzkoušejte, co je ve vašem případě rychlejší.

Související:



  1. mybatis generátor Vzor názvu sloupce nemůže být NULL ani prázdný

  2. Rozdělte hodnoty oddělené čárkami do cílové tabulky s pevným počtem sloupců

  3. Ekvivalent MySQLi kódu MySQL

  4. Jak předat NEW.* do EXECUTE ve funkci spouštění