2015-03-04 12 views
5

Ho appena iniziato a giocare con jsonb su postgres e trovare esempi difficili da trovare online in quanto è un concetto relativamente nuovo. Sto cercando di usare jsonb_each_text per stampare una tabella di chiavi e valori, ma ottenere un csv in una singola colonna.PostgreSQL - jsonb_each

Ho la JSON sotto salvato come jsonb e usarlo per testare le mie domande.

{ 
    "lookup_id": "730fca0c-2984-4d5c-8fab-2a9aa2144534", 
    "service_type": "XXX", 
    "metadata": "sampledata2", 
    "matrix": [ 
    { 
     "payment_selection": "type", 
     "offer_currencies": [ 
      { 
       "currency_code": "EUR", 
       "value": 1220.42 
      } 
     ] 
    } 
    ] 
} 

posso ottenere l'accesso a offer_currencies array con

SELECT element -> 'offer_currencies' -> 0 
FROM test t, jsonb_array_elements(t.json -> 'matrix') AS element 
WHERE element ->> 'payment_selection' = 'type' 

che dà un risultato di "{" valore ": 1220,42, "currency_code": "EUR"}", quindi se faccio funzionare il al di sotto di query ottengo (devo cambiare "per ')

select * from jsonb_each_text('{"value": 1220.42, "currency_code": "EUR"}') 

Key   | Value 
---------------|---------- 
"value"  | "1220.42" 
"currency_code"| "EUR" 

Quindi, utilizzando la teoria di cui sopra ho creato questa query

SELECT jsonb_each_text(data) 
FROM (SELECT element -> 'offer_currencies' -> 0 AS data 
    FROM test t, jsonb_array_elements(t.json -> 'matrix') AS element 
    WHERE element ->> 'payment_selection' = 'type') AS dummy; 

Ma Questo stampa CSV di in una colonna

record 
--------------------- 
"(value,1220.42)" 
"(currency_code,EUR)" 

risposta

12

Il problema principale qui, è che si seleziona l'intera riga come una colonna (PostgreSQL permette che). Puoi sistemarlo con SELECT (jsonb_each_text(data)).* ....

Ma: Non SELECT funzioni di set-ritorno, che spesso può portare a errori (o risultati imprevisti). Invece, usa f.ex. LATERAL join/sub-query:

select first_currency.* 
from test t 
    , jsonb_array_elements(t.json -> 'matrix') element 
    , jsonb_each_text(element -> 'offer_currencies' -> 0) first_currency 
where element ->> 'payment_selection' = 'type' 

Nota: chiamate di funzione nella clausola FROM sono impliciti LATERAL unisce (qui: CROSS JOIN s).

+4

Puoi raccomandare tutte le risorse per l'apprendimento di idiomi del genere ("Non selezionare le funzioni di set-ritorno, che spesso può portare a errori")? – Jay