Solução conforme solicitado
Embora preso a esse design infeliz, a consulta mais rápida seria com
crosstab()
, fornecido pelo módulo adicional tablefunc
. Amplos detalhes nesta resposta relacionada:Para a pergunta feita:
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);
Projeto de banco de dados
Se você não tem um enorme vários campos diferentes, será muito mais simples e eficiente para mesclar todas as três tabelas em uma tabela simples:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Campos sem valores podem ser
NULL
. NULL
o armazenamento é muito barato (basicamente 1 bit por coluna no bitmap NULL):- Quanto espaço em disco é necessário para armazenar um valor NULL usando o banco de dados postgresql?
- Anulável colunas ocupam espaço adicional no PostgreSQL?
Mesmo se você tiver centenas de colunas diferentes e apenas algumas forem preenchidas por entrada, isso ainda usará muito menos espaço em disco.
Sua consulta se torna trivial:
SELECT entry_id, result, output, code, command
FROM enty;
Se você tiver muitas colunas, e isso não for apenas um design equivocado (geralmente, isso pode ser dobrado em muito menos colunas), considere os tipos de dados
hstore
ou json
/ jsonb
(no Postgres 9.4) para EAV
armazenar. Por página "Sobre" do Postgres :
Maximum Columns per Table 250 - 1600 depending on column types
Considere esta resposta relacionada com alternativas:
E esta pergunta sobre casos de uso/problemas típicos de estruturas EAV no dba.SE: