2014-12-06 18 views
5

Ho un problema su cui sto lavorando. Qui di seguito è una query semplificata per mostrare il problema:PostgreSQL: Come accedere alla colonna sul record anonimo

WITH the_table AS (
    SELECT a, b 
    FROM (VALUES('data1', 2), ('data3', 4), ('data5', 6)) x (a, b) 
), my_data AS (
    SELECT 'data7' AS c, array_agg(ROW(a, b)) AS d 
    FROM the_table 
) 
SELECT c, d[array_upper(d, 1)] 
FROM my_data 

Nella mia sezione dei dati, si noterà che sto creando un array da più righe, e l'array viene restituito in una riga con altri dati. Questo array deve contenere le informazioni sia per a e b, e mantenere due valori collegati tra loro. Quello che sembrerebbe avere senso sarebbe usare una riga anonima o un record (voglio evitare di creare effettivamente un tipo composito).

Tutto funziona bene fino a quando non è necessario iniziare a estrarre i dati. Nell'istanza sopra, ho bisogno di accedere all'ultima voce dell'array, che è fatta facilmente usando array_upper, ma poi ho bisogno di accedere al valore in quella che era la colonna b, che non riesco a capire come fare.

In sostanza, in questo momento la query di cui sopra sta tornando:

"data7";"(data5,6)" 

e ho bisogno di tornare

"data7";6 

Come posso fare questo?

NOTA: Mentre nell'esempio sopra sto usando testo e interi come tipi per i miei dati, non sono i veri tipi finali, ma sono piuttosto usati per semplificare l'esempio.

NOTA: Questo sta usando PostgreSQL 9.2

EDIT: Per chiarimenti, Qualcosa come SELECT 'data7', 6 non è quello che sto cercando. Immagina che the_table stia effettivamente tirando dalle tabelle del database e non dall'istruzione WITH che ho inserito per comodità, e non so prontamente quali sono i dati nella tabella.

In altre parole, voglio essere in grado di fare qualcosa del genere:

SELECT c, (d[array_upper(d, 1)]).b 
FROM my_data 

E ottenere questo ritorno:

"data7";6 

In sostanza, una volta che ho messo qualcosa in un record anonima usando la funzione row(), come posso riaverlo? Come posso dividere la parte 'data5' e la parte 6 in modo che non vengano restituiti entrambi in una colonna?

Per un altro esempio:

SELECT ROW('data5', 6) 

fa 'dati5' e 6 ritorno in una colonna. Come posso prendere quella colonna e romperla di nuovo nelle due originali?

spero che chiarisce

+0

Perché è necessario utilizzare gli array per quello che sembra un semplice query di aggregazione? –

+0

Questo è un esempio semplificato per chiarire la mia domanda.La query completa utilizza un'istruzione ricorsiva per raccogliere dati (comprese le righe con gli array) e quindi utilizzo DISTINCT ON su una colonna con un ORDER BY su un'altra colonna per eliminare i dati non necessari generati dalla query ricorsiva. Funziona tutto magnificamente se, ad esempio, ho solo bisogno dei dati della colonna a, ma ho bisogno sia di a che di b, e non posso perdere la loro associazione. Se stavo usando pgsql 9.4, avrei solo a e b in array separati, e quindi userò la multi column non più che deve riassociare a e b più tardi. Ma io sono il 9,2. –

+0

Una pagina che ha una domanda simile con una risposta che non funziona in questo caso può essere trovata qui: http://www.postgresql.org/message-id/[email protected] com –

risposta

1

Se è possibile installare l'estensione hstore:

with the_table as (
    select a, b 
    from (values('data1', 2), ('data3', 4), ('data5', 6)) x (a, b) 
), my_data as (
    select 'data7' as c, array_agg(row(a, b)) as d 
    from the_table 
) 
select c, (avals(hstore(d[array_upper(d, 1)])))[2] 
from my_data 
; 
    c | avals 
-------+------- 
data7 | 6 
+0

Questo è fondamentalmente esattamente quello che sto cercando, tranne per il fatto che devi scaricare un'estensione per farlo funzionare. Non lo so, penso solo che sia un po 'stupido che tu possa costruire una struttura che non puoi smontare a meno che non usi un'estensione. In ogni caso, ti darò un upvote adesso, e se nessuno arriva con una soluzione più nativa (senza estensioni), allora accetterò la tua risposta. –

+0

Domanda per te. Sai come il metodo avals mette due diversi tipi di dati nello stesso array? La maggior parte delle informazioni su Internet dice che non si può avere un array con tipi diversi, eppure le avals sembrano permettere questo. –

+0

Aspetta, ho trovato la risposta alla mia domanda lì. Trasforma tutto in testo e utilizza una matrice di testo. Funziona per il mio esempio con testo e interi, ma potrebbe diventare più di una seccatura per lavorare con i tipi di composito, per esempio. Preferirei trovare qualcosa che mantenga i tipi se possibile. –