Lösning enligt begäran
Även om den här olyckliga designen fastnat skulle den snabbaste frågan vara med crosstab()
, tillhandahållen av tilläggsmodulen tablefunc
. Omfattande detaljer i detta relaterade svar:
För frågan:
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);
Databasdesign
Om du inte har en enorm antal olika fält blir det mycket enklare och effektivare för att slå samman alla tre tabellerna till en enkel tabell:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Fält utan värden kan vara NULL
. NULL
lagring är mycket billig (i princip 1 bit per kolumn i NULL-bitmappen):
- Hur mycket diskutrymme behövs för att lagra ett NULL-värde med postgresql DB?
- Gör nullable kolumner upptar ytterligare utrymme i PostgreSQL?
Även om du har hundratals olika kolumner, och endast ett fåtal fylls per post, kommer detta fortfarande att använda mycket mindre diskutrymme.
Din fråga blir trivial:
SELECT entry_id, result, output, code, command
FROM enty;
Om du har för många kolumner, och det inte bara är en missriktad design (ofta kan denna vikas till mycket färre kolumner), överväg datatyperna hstore
eller json
/ jsonb
(i Postgres 9.4) för EAV
lagring.
Maximum Columns per Table 250 - 1600 depending on column types
Betrakta detta relaterade svar med alternativ:
Och denna fråga om typiska användningsfall / problem med EAV-strukturer på dba.SE: