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

Hvordan forbinder man jsonb-array-elementer i Postgres?

Hvis man antager mindst Postgres 9.5, vil dette gøre jobbet:

SELECT jsonb_pretty(to_jsonb(p)) AS post_row_as_json
FROM  (
   SELECT id, title, author_id, c.content
   FROM   posts p
   LEFT   JOIN LATERAL (
      SELECT jsonb_agg(
               CASE WHEN c.elem->>'type' = 'image' AND i.id IS NOT NULL
                    THEN elem - 'image_id' || jsonb_build_object('image', i)
                    ELSE c.elem END) AS content
      FROM   jsonb_array_elements(p.content) AS c(elem)
      LEFT   JOIN images i ON c.elem->>'type' = 'image'
                          AND i.id = (elem->>'image_id')::uuid
      ) c ON true
   ) p;

Hvordan?

  1. Fjern jsonb matrix, der producerer 1 række pr. matrixelement:

    jsonb_array_elements(p.content) AS c(elem)
    
  2. For hvert element LEFT JOIN til images på de betingelser, som
    a. Nøglen 'type' har værdien 'image':c.elem->>'type' = 'image'
    b. UUID'et i image_id matcher:i.id = (elem->>'image_id')::uuid

  3. For billedtyper, hvor der blev fundet et matchende billede

    c.elem->>'type' = 'image' AND i.id IS NOT NULL
    

    fjern nøglen 'image_id' og tilføj den relaterede billedrække som jsonb værdi:

    elem - 'image_id' || jsonb_build_object('image', i)
    

    Ellers behold det originale element.

  4. Saml de ændrede elementer igen til et nyt content kolonne med jsonb_agg() .

  5. Ubetinget LEFT JOIN LATERAL resultatet til posts og vælg alle kolonner, erstat kun p.content med den genererede erstatning c.content

  6. I den ydre SELECT , konverter hele rækken til jsonb med en simpel to_jsonb() .

Alle jsonb funktioner er dokumenteret i manualen her.




  1. Oracle:Indsæt rækketypedata i en anden tabel

  2. Sådan masseindsætter du kun nye rækker i PostreSQL

  3. Ecto bygge flere assoc

  4. MYSQL-udløseren slettes automatisk