Git Product home page Git Product logo

jsonb-flattening-patterns's Introduction

PostgreSQL JSONB flattening

JSONB subscripting (PG14+) syntax

Note

Arrow syntax (object->'attribute', object->>'attribute') for versions prior to PG14 or as a matter of personal taste

create table the_table (
 id integer,
 name text,
 details jsonb
);

JSONB object per record

insert into the_table 
values
(1, 'one',   '{"x":101, "y":201, "z":false, "more":{"weight":23.5, "created":"2023-12-10"}}'),
(2, 'two',   '{"x":102, "y":202, "z":true, "more":{"weight":8.72}}'),
(3, 'three', '{"x":103, "y":203, "more":{"created":"2024-01-20"}}');
  • Using select list expressions only
select id, 
       name, 
       details['x']::numeric as length, 
       details['y']::numeric as width, 
       details['z']::boolean as is_available,
       details['more']['weight']::numeric as weight,
       details['more']['created']::text::date as created
from the_table;

Note

Note the cast of jsonb details['more']['created'] first to text and then to date as a cast of jsonb to date does not exist. details->'more'->>'created' is text and can be cast to date directly.

  • Using JSONB_TO_RECORD
select id, 
       name,
       j.x as length,
       j.y as width,
       j.z as is_available,
       j.more['weight']::numeric as weight,
       j.more['created']::text::date as created
from the_table
 cross join lateral jsonb_to_record(details) as j(x numeric, y numeric, z boolean, more jsonb);
id name length width is_available weight created
1 one 101 201 false 23.5 2023-12-10
2 two 102 202 true 8.72
3 three 103 203 2024-01-20

Deeply nested data. JSONB array per record

truncate the_table;
insert into the_table 
values
(1, 'one', '[{"x":101, "y":201, "z":false, "more":{"weight":23.5, "even_more":{"created":"2023-12-10"}}},
             {"x":102, "y":202, "z":true, "more":{"weight":8.72}},
             {"x":103, "y":203, "more":{"even_more":{"created":"2024-01-20"}}}]'
),
(2, 'two', '[{"x":111, "y":211, "z":true, "more":{"weight":123.5, "even_more":{"created":"2023-12-11"}}},
             {"x":112, "y":212, "z":false, "more":{"weight":18.72, "location_ids":[91, 92, 93]}},
             {"x":113, "y":233, "more":{"even_more":{"created":"2024-01-21"}}}]'
);
  • Using JSONB_ARRAY_ELEMENTS
select id, 
       name, 
       jdata['x']::numeric as length, 
       jdata['y']::numeric as width,
       case when jdata['z'] is null then 'Do not count on it'
            else case when jdata['z']::boolean then 'Yes' else 'Unfortunately not' end
       end as available,
       jdata['more']['weight']::numeric as weight,
       jdata['more']['even_more']['created']::text::date as created,
       loc::integer as loc_id
from the_table 
 cross join lateral jsonb_array_elements(details) as jdata
 left  join lateral jsonb_array_elements_text(jdata['more']['location_ids']) as l(loc) on true
order by id, weight nulls first;
  • Using JSONB_TO_RECORDSET
select id, 
       name, 
       x as length, 
       y as width, 
       case when z is null then 'Do not count on it'
            else case when z then 'Yes' else 'Unfortunately not' end
       end as available,
       more['weight']::numeric as weight,
       more['even_more']['created']::text::date as created,
       loc::integer as loc_id
from the_table 
 cross join lateral jsonb_to_recordset(details) as (x numeric, y numeric, z boolean, more jsonb)
 left  join lateral jsonb_array_elements_text(more['location_ids']) as l(loc) on true
order by id, weight nulls first;
id name length width available weight created loc_id
1 one 103 203 Do not count on it 2024-01-20
1 one 102 202 Yes 8.72
1 one 101 201 Unfortunately not 23.5 2023-12-10
2 two 113 233 Do not count on it 2024-01-21
2 two 112 212 Unfortunately not 18.72 91
2 two 112 212 Unfortunately not 18.72 92
2 two 112 212 Unfortunately not 18.72 93
2 two 111 211 Yes 123.5 2023-12-11

Note

Verbose cross join lateral used for explicitness, can be replaced by a comma

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.