CodeGym /Kursy /SQL SELF /Wyciąganie zagnieżdżonych danych: jsonb_to_records...

Wyciąganie zagnieżdżonych danych: jsonb_to_recordset()

SQL SELF
Poziom 33 , Lekcja 3
Dostępny

Lecimy dalej do bardziej zaawansowanych przypadków pracy z danymi w formacie JSONB — wyciągania zagnieżdżonych danych i zamiany ich na wiersze tabeli. Po co to w ogóle robić? Mega proste! Wyobraź sobie, że dostajesz JSON-owy obiekt z tablicą zakupów i masz policzyć sumę wszystkich zakupów albo pokazać je w tabelce do raportu. Zaraz to ogarniemy!

Czemu nie można po prostu pracować z JSON-em jak z tekstem albo strukturą? Zobaczmy na przykładzie. W wielu realnych apkach dane trzymane są jako tablice JSON:

[
  { "id": 1, "product_name": "Laptop", "price": 1200 },
  { "id": 2, "product_name": "Smartphone", "price": 800 },
  { "id": 3, "product_name": "Tablet", "price": 400 }
]

To wygodne, ale jak chcesz analizować dane, często musisz zamienić tablicę na tabelę, żeby móc filtrować, sortować czy agregować. Wyobraź sobie: „Wszystkie zamówienia powyżej 500 dolarów”. Sam JSONB nie pozwala na to tak wygodnie, jakby się chciało. I tu właśnie wchodzi jsonb_to_recordset().

Praca z jsonb_to_recordset()

Funkcja jsonb_to_recordset() pozwala zamienić tablicę obiektów JSONB na wiersze tabeli. Każdy element tablicy staje się wierszem, a klucze zamieniają się w kolumny. Ta funkcja jest niezastąpiona, gdy dane są mocno zagnieżdżone albo masz tablice obiektów.

Składnia

SELECT *
FROM jsonb_to_recordset('[ tablica JSONB ]') AS alias(kolumna1 TYP, kolumna2 TYP, ...);
  • [ tablica JSONB ]: tablica obiektów JSON, z której wyciągamy dane.
  • AS alias: tworzymy tymczasową nazwę dla wynikowej tabeli.
  • kolumna1 TYP, kolumna2 TYP: określamy, jak mają się nazywać kolumny i jakie typy danych będą miały (np. INTEGER, TEXT, NUMERIC).

Przykład: zamiana tablicy JSONB na wiersze

Załóżmy, że mamy taką tabelę:

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_name TEXT,
    products JSONB
);

I w tabeli są takie dane:

id customer_name products
1 John [{"id":1, "product_name":"Laptop", "price":1200}, {"id":2, "product_name":"Mouse", "price":50}]
2 Alice [{"id":3, "product_name":"Smartphone", "price":800}, {"id":4, "product_name":"Charger", "price":30}]

Teraz zadanie: wyświetlić listę wszystkich produktów ze wszystkich zamówień w formie tabeli. Tak to robimy z jsonb_to_recordset():

SELECT
    o.id AS order_id,
    o.customer_name,
    p.id AS product_id,
    p.product_name,
    p.price
FROM
    orders AS o,
    jsonb_to_recordset(o.products) AS p(id INTEGER, product_name TEXT, price NUMERIC);

Wynik:

order_id customer_name product_id product_name price
1 John 1 Laptop 1200
1 John 2 Mouse 50
2 Alice 3 Smartphone 800
2 Alice 4 Charger 30

Przykład: filtrowanie danych

Podkręcamy poziom. Chcemy pokazać tylko te produkty z zamówień, które kosztują więcej niż 100 dolarów:

SELECT
    o.id AS order_id,
    o.customer_name,
    p.id AS product_id,
    p.product_name,
    p.price
FROM
    orders AS o,
    jsonb_to_recordset(o.products) AS p(id INTEGER, product_name TEXT, price NUMERIC)
WHERE
    p.price > 100;

Wynik:

order_id customer_name product_id product_name price
1 John 1 Laptop 1200
2 Alice 3 Smartphone 800

Przykład: agregacja danych

A co powiesz na policzenie sumy wszystkich produktów w zamówieniach? Po prostu używamy funkcji agregujących:

SELECT
    o.customer_name,
    SUM(p.price) AS total_amount
FROM
    orders AS o,
    jsonb_to_recordset(o.products) AS p(id INTEGER, product_name TEXT, price NUMERIC)
GROUP BY
    o.customer_name;

Wynik:

customer_name total_amount
John 1250
Alice 830

Ważne uwagi

Upewnij się, że struktura tablicy JSON jest taka sama dla wszystkich obiektów. Jeśli jakiś obiekt ma inne klucze albo zagnieżdżone struktury, możesz dostać błąd albo dziwne wyniki.

Dobrze ustaw typy danych dla wyciąganych kolumn. Na przykład, jeśli klucz to data, użyj DATE, dla liczb — NUMERIC albo INTEGER.

Pamiętaj, że jsonb_to_recordset() działa tylko na tablicach JSONB; z pojedynczymi obiektami nie zadziała.

Typowe błędy i jak ich unikać

Zły typ danych: jeśli w tablicy JSONB są wartości z różnymi typami (np. string zamiast liczby), będzie błąd. Najlepiej przerobić dane na właściwy format przed użyciem funkcji.

Zły klucz: jeśli klucz nie istnieje w którymś obiekcie tablicy, będzie błąd. Sprawdź strukturę danych przed zapytaniem.

Brak danych: jeśli kolumna JSONB jest pusta (NULL), funkcja nie zwróci wyników. W takich przypadkach dodaj sprawdzenie, np. COALESCE().

Praktyczne zastosowanie

jsonb_to_recordset() jest szeroko używane w realnych zadaniach, np. do obsługi zamówień, analizy raportów, logowania akcji użytkowników czy przetwarzania zewnętrznych API. Przykłady:

  • W sklepach internetowych łatwo zamienisz tablice produktów na tabele i zrobisz raporty.
  • REST API może zwracać dane w formacie JSON, które wygodnie analizować w PostgreSQL.
  • Apki analityczne często używają tej funkcji do ogarniania skomplikowanych, wielopoziomowych danych.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION