sql >> Databasteknik >  >> RDS >> PostgreSQL

postgresql - fråga för att bygga upp json

En dynamisk lösning kräver lite arbete.

Först behöver vi en funktion för att konvertera en textmatris och ett värde till ett jsonb-objekt.

create or replace function keys_to_object(keys text[], val text)
returns jsonb language plpgsql as $$
declare
    i int;
    rslt jsonb = to_jsonb(val);
begin
    for i in select generate_subscripts(keys, 1, true) loop
        rslt := jsonb_build_object(keys[i], rslt);
    end loop;
    return rslt;
end $$;

select keys_to_object(array['key', 'subkey', 'subsub'], 'value');

              keys_to_object              
------------------------------------------
 {"key": {"subkey": {"subsub": "value"}}}
(1 row)

Därefter en annan funktion för att slå samman jsonb-objekt (se Sammanfoga JSONB-värden i PostgreSQL ).

create or replace function jsonb_merge(a jsonb, b jsonb) 
returns jsonb language sql as $$ 
select 
    jsonb_object_agg(
        coalesce(ka, kb), 
        case 
            when va isnull then vb 
            when vb isnull then va 
            when jsonb_typeof(va) <> 'object' or jsonb_typeof(vb) <> 'object' then vb 
            else jsonb_merge(va, vb) end 
        ) 
    from jsonb_each(a) e1(ka, va) 
    full join jsonb_each(b) e2(kb, vb) on ka = kb 
$$;

select jsonb_merge('{"key": {"subkey1": "value1"}}', '{"key": {"subkey2": "value2"}}');

                     jsonb_merge                     
-----------------------------------------------------
 {"key": {"subkey1": "value1", "subkey2": "value2"}}
(1 row) 

Slutligen, låt oss skapa ett aggregat baserat på ovanstående funktion,

create aggregate jsonb_merge_agg(jsonb)
(
    sfunc = jsonb_merge,
    stype = jsonb
);

och vi är klara:

select jsonb_pretty(jsonb_merge_agg(keys_to_object(key, translate(value, '{}"', '[]'))))
from test_table;

                 jsonb_pretty                 
----------------------------------------------
 {                                           +
     "cogs": {                               +
         "props1": {                         +
             "id": "26",                     +
             "value": "100",                 +
             "dimensions": "[200, 300]"      +
         },                                  +
         "props2": {                         +
             "id": "27",                     +
             "value": "200",                 +
             "dimensions": "[700, 800]"      +
         },                                  +
         "display": "Giant Cog",             +
         "description": "some awesome cog"   +
     },                                      +
     "widgets": {                            +
         "props1": {                         +
             "id": "28",                     +
             "value": "100",                 +
             "dimensions": "[200, 300]"      +
         },                                  +
         "props2": {                         +
             "id": "29",                     +
             "value": "200",                 +
             "dimensions": "[900, 1000]"     +
         },                                  +
         "display": "Giant Widget",          +
         "description": "some awesome widget"+
     }                                       +
 }
(1 row)



  1. Läs e-post imap php

  2. Utgivningsdatum för Mysql-fråga minus 7 dagar

  3. Flytta postgresql datakluster

  4. Ta reda på om en partition är komprimerad i SQL Server (T-SQL)