PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

SQL :Créer un enregistrement complet à partir de 2 tables

Solution comme demandé

Bien que coincé avec cette conception malheureuse, la requête la plus rapide serait avec crosstab() , fourni par le module supplémentaire tablefunc . De nombreux détails dans cette réponse connexe :

Pour la question posée :

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);

Conception de la base de données

Si vous n'avez pas un énorme nombre de champs différents, ce sera beaucoup plus simple et plus efficace pour fusionner les trois tableaux en un seul tableau :

CREATE TABLE entry (
   entry_id serial PRIMARY KEY
  ,field1   text
  ,field2   text
  , ... more fields
);

Les champs sans valeurs peuvent être NULL . NULL le stockage est très bon marché (essentiellement 1 bit par colonne dans le bitmap NULL):

Même si vous avez des centaines de colonnes différentes et que seules quelques-unes sont remplies par entrée, cela utilisera toujours beaucoup moins d'espace disque.

Votre requête devient triviale :

SELECT entry_id, result, output, code, command
FROM   enty;

Si vous avez trop de colonnes, et que ce n'est pas seulement une conception erronée (souvent, cela peut être plié en beaucoup moins de colonnes), considérez les types de données hstore ou json / jsonb (dans Postgres 9.4) pour EAV stockage.

Par la page "À propos" de Postgres :

Maximum Columns per Table   250 - 1600 depending on column types

Considérez cette réponse connexe avec des alternatives :

Et cette question sur les cas d'utilisation/problèmes typiques des structures EAV sur dba.SE :