sql >> Database >  >> RDS >> PostgreSQL

Hoe voeg je jsonb-array-elementen toe in Postgres?

Uitgaande van ten minste Postgres 9.5, zal dit het werk doen:

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;

Hoe?

  1. Unnes de jsonb array, waardoor 1 rij per array-element wordt geproduceerd:

    jsonb_array_elements(p.content) AS c(elem)
    
  2. Voor elk element LEFT JOIN naar images op de voorwaarden die
    a. De toets 'type' heeft de waarde 'image':c.elem->>'type' = 'image'
    b. De UUID in image_id komt overeen met:i.id = (elem->>'image_id')::uuid

  3. Voor afbeeldingstypen, waar een overeenkomende afbeelding is gevonden

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

    verwijder de sleutel 'image_id' en voeg de gerelateerde afbeeldingsrij toe als jsonb waarde:

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

    Bewaar anders het originele element.

  4. Voeg de gewijzigde elementen opnieuw samen tot een nieuwe content kolom met jsonb_agg() .

  5. Onvoorwaardelijk LEFT JOIN LATERAL het resultaat naar posts en selecteer alle kolommen, vervang alleen p.content met de gegenereerde vervanging c.content

  6. In de buitenste SELECT , converteer de hele rij naar jsonb met een simpele to_jsonb() .

Alle jsonb functies worden hier in de handleiding beschreven.




  1. mariadb-connector J Aurora Snelle failover-implementatie

  2. Wat is de volgorde van uitvoering van deze SQL-instructie?

  3. Vastgelopen in fout 2 met mysql met XAMPP

  4. Ecto bouwt meerdere assoc