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

Hurtig forespørgsel for at udføre normalisering på SQL-data

Dette er mit andet svar, udvidet til tre kolonner:

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

Resultater:

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)
 

Edit:Dette ser ud til at fungere godt nok, og jeg hader at se den ned-stemme, jeg satte der, så ubrugelig redigering (CrazyCasta).



  1. SQL - rækkefølge efter listerækkefølge

  2. Mysql unik begrænsning, der tillader en enkelt række for en kombination

  3. Langsom forespørgsel i Java af JDBC, men ikke i andre systemer (TOAD)

  4. Mysql2::Fejl:Adgang nægtet for brugeren 'test'@'localhost' til databasen 'depot_test'