PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Бърза заявка за нормализиране на SQL данни

Това е другият ми отговор, разширен в три колони:

        -- Some test data
CREATE TABLE the_table
        ( id SERIAL NOT NULL PRIMARY KEY
        , name varchar
        , a INTEGER
        , b varchar
        , c varchar
        );
INSERT INTO the_table(name, a,b,c) VALUES
 ( 'Chimpanzee' , 1, 'mammals', 'apes' )
,( 'Urang Utang' , 1, 'mammals', 'apes' )
,( 'Homo Sapiens' , 1, 'mammals', 'apes' )
,( 'Mouse' , 2, 'mammals', 'rodents' )
,( 'Rat' , 2, 'mammals', 'rodents' )
,( 'Cat' , 3, 'mammals', 'felix' )
,( 'Dog' , 3, 'mammals', 'canae' )
        ;

        -- [empty] table to contain the "squeezed out" domain {a,b,c}
CREATE TABLE abc_table
        ( id SERIAL NOT NULL PRIMARY KEY
        , a INTEGER
        , b varchar
        , c varchar
        , UNIQUE (a,b,c)
        );

        -- The original table needs a "link" to the new table
ALTER TABLE the_table
        ADD column abc_id INTEGER -- NOT NULL
        REFERENCES abc_table(id)
        ;
        -- FK constraints are helped a lot by a supportive index.
CREATE INDEX abc_table_fk ON the_table (abc_id);

        -- Chained query to:
        -- * populate the domain table
        -- * initialize the FK column in the original table
WITH ins AS (
        INSERT INTO abc_table(a,b,c)
        SELECT DISTINCT a,b,c
        FROM the_table a
        RETURNING *
        )
UPDATE the_table ani
SET abc_id = ins.id
FROM ins
WHERE ins.a = ani.a
AND ins.b = ani.b
AND ins.c = ani.c
        ;

        -- Now that we have the FK pointing to the new table,
        -- we can drop the redundant columns.
ALTER TABLE the_table DROP COLUMN a, DROP COLUMN b, DROP COLUMN c;

SELECT * FROM the_table;
SELECT * FROM abc_table;

        -- show it to the world
SELECT a.*
        , c.a, c.b, c.c
FROM the_table a
JOIN abc_table c ON c.id = a.abc_id
        ;

Резултати:

CREATE TABLE
INSERT 0 7
CREATE TABLE
ALTER TABLE
CREATE INDEX
UPDATE 7
ALTER TABLE
 id |     name     | abc_id 
----+--------------+--------
  1 | Chimpanzee   |      4
  2 | Urang Utang  |      4
  3 | Homo Sapiens |      4
  4 | Mouse        |      3
  5 | Rat          |      3
  6 | Cat          |      1
  7 | Dog          |      2
(7 rows)

 id | a |    b    |    c    
----+---+---------+---------
  1 | 3 | mammals | felix
  2 | 3 | mammals | canae
  3 | 2 | mammals | rodents
  4 | 1 | mammals | apes
(4 rows)

 id |     name     | abc_id | a |    b    |    c    
----+--------------+--------+---+---------+---------
  1 | Chimpanzee   |      4 | 1 | mammals | apes
  2 | Urang Utang  |      4 | 1 | mammals | apes
  3 | Homo Sapiens |      4 | 1 | mammals | apes
  4 | Mouse        |      3 | 2 | mammals | rodents
  5 | Rat          |      3 | 2 | mammals | rodents
  6 | Cat          |      1 | 3 | mammals | felix
  7 | Dog          |      2 | 3 | mammals | canae
(7 rows)

Редактиране:Това изглежда работи достатъчно добре и мразя да видя отрицателния вот, който поставих там, така че безполезна редакция (CrazyCasta).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Отчитане на лятното часово време в Postgres, когато избирате планирани елементи

  2. Не мога да намеря заглавката 'libpq-fe.h при опит за инсталиране на pg gem

  3. PostgreSQL:сериен срещу самоличност

  4. postgresql json агрегат

  5. Защита на ниво ред с помощта на Prisma и Postgres