CodeGym /Cursos /SQL SELF /Extraindo dados aninhados: jsonb_to_recordset()

Extraindo dados aninhados: jsonb_to_recordset()

SQL SELF
Nível 33 , Lição 3
Disponível

Agora bora pra cenários mais cabulosos de trabalhar com dados em formato JSONB — extrair dados aninhados e transformar eles em linhas de tabela. Tu pode perguntar: pra quê isso? Simples! Imagina que te deram um objeto JSON com um array de compras e pediram pra calcular o total de todas as compras ou mostrar elas em formato de tabela pra um relatório. Bora ver como faz isso agora!

Por que não dá pra trabalhar com JSON só como texto ou estrutura? Olha só esse cenário. Em muitos apps reais, os dados ficam guardados como arrays de JSON:

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

Isso é prático, mas na hora de analisar os dados, quase sempre tu precisa transformar o array em tabela pra fazer coisas tipo filtrar, ordenar e agregar. Imagina: “Todos os pedidos acima de 500 dólares”. O JSONB sozinho não deixa fazer isso de um jeito tão fácil quanto a gente quer. É aí que entra o jsonb_to_recordset().

Trabalhando com jsonb_to_recordset()

A função jsonb_to_recordset() transforma um array de objetos JSONB em linhas de tabela. Ela literalmente pega cada item do array e vira uma linha, e as chaves viram colunas. Essa função é indispensável quando os dados são bem aninhados ou têm arrays de objetos.

Sintaxe

SELECT *
FROM jsonb_to_recordset('[ array JSONB ]') AS alias(coluna1 TIPO, coluna2 TIPO, ...);
  • [ array JSONB ]: o array de objetos JSON de onde a gente vai tirar os dados.
  • AS alias: cria um nome temporário pra tabela que vai sair.
  • coluna1 TIPO, coluna2 TIPO: define como vão se chamar as colunas e quais tipos de dados elas vão usar (tipo INTEGER, TEXT, NUMERIC).

Exemplo: transformando um array JSONB em linhas

Imagina que a gente tem essa tabela:

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

E na tabela tem esses dados:

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}]

Agora o desafio: mostrar a lista de todos os produtos de todos os pedidos em formato de tabela. Olha como faz usando 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);

Resultado:

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

Exemplo: filtrando dados

Bora deixar mais interessante. Queremos mostrar só os produtos dos pedidos que custam mais de 100 dólares:

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;

Resultado:

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

Exemplo: agregando dados

Que tal calcular o total de todos os produtos nos pedidos? Só usar funções de agregação:

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;

Resultado:

customer_name total_amount
John 1250
Alice 830

Dicas importantes

Garante que a estrutura do array JSON seja igual pra todos os objetos. Se algum objeto tiver chaves diferentes ou estruturas aninhadas, pode dar erro ou um resultado estranho.

Define certinho os tipos de dados das colunas que tu vai extrair. Por exemplo, se a chave tem uma data, usa DATE, pra números — NUMERIC ou INTEGER.

Lembra que jsonb_to_recordset() só transforma arrays JSONB; com objetos únicos ela não funciona.

Erros comuns e como evitar

Usar tipos de dados errados: se no array JSONB tiver valores com tipos diferentes (tipo string no lugar de número), vai dar erro. Recomendo converter os dados pro formato certo antes de usar a função.

Acessar chaves erradas: se uma chave não existir em algum objeto do array, vai dar erro. Confere a estrutura dos dados antes de rodar a query.

Falta de dados: se a coluna JSONB estiver vazia (NULL), a função não retorna nada. Nesses casos, usa checagem tipo COALESCE().

Aplicação prática

jsonb_to_recordset() é muito usado em tarefas reais, tipo processar pedidos, analisar relatórios, logar ações de usuário e tratar dados de APIs externas. Por exemplo:

  • Em lojas online, dá pra transformar arrays de produtos em tabelas e montar relatórios fácil.
  • REST API pode devolver dados em JSON, que tu analisa de boa com PostgreSQL.
  • Apps de analytics usam muito essa função pra processar dados complexos e cheios de níveis.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION