Solución según lo solicitado
Si bien se quedó con este desafortunado diseño, la consulta más rápida sería con crosstab()
, proporcionada por el módulo adicional tablefunc
. Amplios detalles en esta respuesta relacionada:
Para la pregunta formulada:
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);
Diseño de base de datos
Si no tienes un enorme cantidad de campos diferentes, será mucho más simple y eficiente para fusionar las tres tablas en una tabla simple:
CREATE TABLE entry (
entry_id serial PRIMARY KEY
,field1 text
,field2 text
, ... more fields
);
Los campos sin valores pueden ser NULL
. NULL
el almacenamiento es muy barato (básicamente 1 bit por columna en el mapa de bits NULL):
- ¿Cuánto espacio en disco se necesita para almacenar un valor NULL usando la base de datos postgresql?
- Do anulable ¿Las columnas ocupan espacio adicional en PostgreSQL?
Incluso si tiene cientos de columnas diferentes y solo se llenan unas pocas por entrada, usará mucho menos espacio en disco.
Tu consulta se vuelve trivial:
SELECT entry_id, result, output, code, command
FROM enty;
Si tiene demasiadas columnas, y eso no es solo un diseño equivocado (a menudo, esto se puede plegar en muchas menos columnas), considere los tipos de datos hstore
o json
/ jsonb
(en Postgres 9.4) para EAV
almacenamiento.
Según la página "Acerca de" de Postgres :
Maximum Columns per Table 250 - 1600 depending on column types
Considere esta respuesta relacionada con alternativas:
Y esta pregunta sobre casos de uso típicos/problemas de estructuras EAV en dba.SE: