sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan kan jeg flette poster i to JSON-arrays?

Forudsat datatype jsonb og at du ønsker at flette poster for hvert JSON-array, der deler den samme 'id'-værdi.

Postgres 9.5

gør det lettere med den nye sammenkædning operator || for jsonb værdier :

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 sørger for, at du ikke mister poster uden match i det andet array.

Typen jsonb har den bekvemme egenskab kun at beholde den seneste værdi for hver nøgle i posten. Derfor flettes den duplikerede 'id'-nøgle i resultatet automatisk.

Postgres 9.5-manualen anbefaler også:

Postgres 9.4

Er lidt mindre praktisk. Min idé ville være at udtrække array-elementer og derefter udtrække alle nøgle/værdi-par, UNION begge resultater samles til en enkelt ny jsonb værdier pr. id-værdi og til sidst aggregeres i en enkelt matrix.

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;

Castet til jsonb fjerner dubletnøgler. Alternativt kan du bruge UNION at folde dubletter (for eksempel hvis du vil have json som resultat). Test, hvad der er hurtigere for dit tilfælde.

Relateret:



  1. skabe materialiseret oversigt til årsrapport baseret på langsom funktion

  2. Hvordan bruger man Oracle ORDER BY og ROWNUM korrekt?

  3. Med VBA skal du finde den version af MySQL ODBC-driveren, der er installeret i Windows

  4. Kan ikke oprette PoolableConnectionFactory