Soluzione come richiesto
Sebbene bloccato con questo sfortunato design, la query più veloce sarebbe con crosstab()
, fornito dal modulo aggiuntivo tablefunc
. Ampi dettagli in questa risposta correlata:
Per la domanda posta:
SELECT * FROM crosstab(
$$SELECT e.id, ef.name, ef.value
FROM entry e
LEFT JOIN entry_fields ef
ON ef.entryid = e.id
AND ef.name = ANY ('{result,output,code,command}'::text[])
ORDER BY 1, 2$$
,$$SELECT unnest('{result,output,code,command}'::text[])$$
) AS ct (id int, result text, output text, code text, command text);
Progettazione database
Se non hai un enorme numero di campi diversi, sarà molto più semplice ed efficiente per unire tutte e tre le tabelle in una semplice tabella:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
I campi senza valori possono essere NULL
. NULL
lo spazio di archiviazione è molto economico (fondamentalmente 1 bit per colonna nella bitmap NULL):
- Quanto spazio su disco è necessario per memorizzare un valore NULL utilizzando il DB postgresql?
- Fai nullable le colonne occupano spazio aggiuntivo in PostgreSQL?
Anche se hai centinaia di colonne diverse e solo poche vengono riempite per voce, questo utilizzerà comunque molto meno spazio su disco.
La tua domanda diventa banale:
SELECT entry_id, result, output, code, command
FROM enty;
Se hai troppe colonne e questo non è solo un design fuorviante (spesso può essere ripiegato in un numero molto inferiore di colonne), considera i tipi di dati hstore
o json
/ jsonb
(in Postgres 9.4) per EAV
archiviazione.
Per la pagina "Informazioni" di Postgres :
Maximum Columns per Table 250 - 1600 depending on column types
Considera questa risposta correlata con alternative:
E questa domanda sui casi d'uso/problemi tipici delle strutture EAV su dba.SE: