sql >> Database teknologi >  >> RDS >> PostgreSQL

SQL :Opret en fuld post fra 2 tabeller

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

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.

Per Postgres "Om"-side :

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:



  1. MYSQL:Ledige / besatte lokaler som nu

  2. masseopdatering af en liste over værdier fra en liste over id'er

  3. MySQL indsæt række på dublet nøgle opdatering flere kolonner

  4. Sådan opdages og forhindres uventet vækst af SQL Server-databasen TempDB