PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Meratakan kolom JSONB bersarang Postgres

Saya mengembangkan ini menggunakannya di psql .Untuk memeriksa kode saya membuat tampilan kecil t1 :

CREATE VIEW t1 AS (
       SELECT 1 AS id, '{"brother": {"first_name":"Sam", "last_name":"Smith"}, "sister": {"first_name":"Sally", "last_name":"Smith"}}'::jsonb AS jsonb
 UNION SELECT 2, '{"sister": {"first_name":"Jill", "last_name":"Johnson"}}'
 UNION SELECT 3, '{"sister": {"first_name":"Jill", "x_name":"Johnson"}}'
);

Tugas pertama adalah menemukan daftar kemungkinan kunci:

WITH fields AS (
     SELECT DISTINCT jff.key
       FROM t1,
            jsonb_each(jsonb) AS jf,
            jsonb_each(jf.value) AS jff
)
SELECT * FROM fields;

Hasilnya adalah:

    key     
------------
 first_name
 last_name
 x_name

Langkah selanjutnya adalah generate query:

SELECT 'SELECT id, jf.key as sibling, ' || (
    WITH fields AS (
         SELECT DISTINCT jff.key
           FROM t1,
                jsonb_each(jsonb) AS jf,
                jsonb_each(jf.value) AS jff
    )
    SELECT string_agg('jf.value->>''' || key || ''' as "' || key || '"', ',' ORDER BY key)
      FROM fields
)
|| ' FROM t1, jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;' AS cmd;

Ini mengembalikan:

                                                                                  cmd                                                                                   
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 SELECT id, jf.key as sibling,jf.value->>'first_name' as "first_name",jf.value->>'last_name' as "last_name",jf.value->>'x_name' as "x_name" FROM t1, jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;
(1 row)

Untuk menetapkan hasil sebagai variabel psql saya menggunakan gset :

\gset

Setelah itu Anda dapat memanggil kueri:

:cmd

 id | sibling | first_name | last_name | x_name  
----+---------+------------+-----------+---------
  1 | brother | Sam        | Smith     | 
  1 | sister  | Sally      | Smith     | 
  2 | sister  | Jill       | Johnson   | 
  3 | sister  | Jill       |           | Johnson
(4 rows)

Untuk menjalankannya dari bahasa eksternal, Anda dapat membuat fungsi postgres daripada mengembalikan perintah SQL:

CREATE OR REPLACE FUNCTION build_query(IN tname text, OUT cmd text)  AS $sql$
BEGIN 
    EXECUTE $cmd$
            SELECT 'SELECT id, jf.key as sibling, ' || (
                    WITH fields AS (
                        SELECT DISTINCT jff.key
                          FROM t1,
                               jsonb_each(jsonb) AS jf,
                               jsonb_each(jf.value) AS jff
                    )
                    SELECT string_agg('jf.value->>''' || key || ''' as "' || key || '"', ',' ORDER BY key)
                      FROM fields
                )
        || ' FROM $cmd$ || quote_ident(tname) || $cmd$ , jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;'$cmd$ INTO cmd;
    RETURN;
END;
$sql$ LANGUAGE plpgsql;

SELECT * FROM build_query('t1');
                                                                                               cmd                                                                                               
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 SELECT id, jf.key as sibling, jf.value->>'first_name' as "first_name",jf.value->>'last_name' as "last_name",jf.value->>'x_name' as "x_name" FROM t1 , jsonb_each(jsonb) AS jf ORDER BY 1, 2, 3;
(1 row)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Setara dengan unpivot() di PostgreSQL

  2. Bagaimana cara mensimulasikan kebuntuan di PostgreSQL?

  3. Kesalahan dalam membuat URUTAN saat memulihkan database PostgreSQL

  4. catatan buruk kesalahan SSL MAC antara Java dan PortgreSQL

  5. Tidak dapat masuk ke postgres pengguna sistem