Løsning som anmodet
Mens du sidder fast med dette uheldige design, ville den hurtigste forespørgsel være med crosstab()
, leveret af det ekstra modul tablefunc
. Mange detaljer i dette relaterede svar:
For det stillede spørgsmål:
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);
Databasedesign
Hvis du ikke har en enorm antal forskellige felter, vil det være meget enklere og mere effektivt at flette alle tre tabeller til en simpel tabel:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Felter uden værdier kan være NULL
. NULL
opbevaring er meget billig (grundlæggende 1 bit pr. kolonne i NULL bitmap):
- Hvor meget diskplads er nødvendig for at gemme en NULL-værdi ved hjælp af postgresql DB?
- Gør nullable kolonner optager ekstra plads i PostgreSQL?
Selvom du har hundredvis af forskellige kolonner, og kun få er udfyldt pr. post, vil dette stadig bruge meget mindre diskplads.
Din forespørgsel bliver triviel:
SELECT entry_id, result, output, code, command
FROM enty;
Hvis du har for mange kolonner, og det ikke bare er et forkert design (ofte kan dette foldes til meget færre kolonner), så overvej datatyperne hstore
eller json
/ jsonb
(i Postgres 9.4) for EAV
opbevaring.
Maximum Columns per Table 250 - 1600 depending on column types
Overvej dette relaterede svar med alternativer:
Og dette spørgsmål om typiske use cases / problemer med EAV-strukturer på dba.SE: