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

Instruction SQL CREATE TABLE … AS SELECT

Le SQL CREATE TABLE ... AS SELECT vous permet d'insérer les résultats d'une requête dans une nouvelle table.

Exemple de base

Voici un exemple de base pour illustrer la sélection et l'insertion des données dans une nouvelle table.

CREATE TABLE Pets2 AS
(SELECT * FROM Pets);

Cela crée une nouvelle table appelée Pets2 (avec la même définition que Pets ) et y insère les résultats de la requête.

La norme SQL requiert des parenthèses autour de la clause de sous-requête, mais elles peuvent être facultatives dans votre SGBD (par exemple PostgreSQL).

Si nous sélectionnons les deux tables, nous pouvons voir qu'elles ont toutes les deux les mêmes données.

barney=# SELECT * FROM Pets;
 petid | pettypeid | ownerid | petname |    dob     
-------+-----------+---------+---------+------------
     1 |         2 |       3 | Fluffy  | 2020-11-20
     2 |         3 |       3 | Fetch   | 2019-08-16
     3 |         2 |       2 | Scratch | 2018-10-01
     4 |         3 |       3 | Wag     | 2020-03-15
     5 |         1 |       1 | Tweet   | 2020-11-28
     6 |         3 |       4 | Fluffy  | 2020-09-17
     7 |         3 |       2 | Bark    | 
     8 |         2 |       4 | Meow    | 
(8 rows)

barney=# SELECT * FROM Pets2;
 petid | pettypeid | ownerid | petname |    dob     
-------+-----------+---------+---------+------------
     1 |         2 |       3 | Fluffy  | 2020-11-20
     2 |         3 |       3 | Fetch   | 2019-08-16
     3 |         2 |       2 | Scratch | 2018-10-01
     4 |         3 |       3 | Wag     | 2020-03-15
     5 |         1 |       1 | Tweet   | 2020-11-28
     6 |         3 |       4 | Fluffy  | 2020-09-17
     7 |         3 |       2 | Bark    | 
     8 |         2 |       4 | Meow    | 
(8 rows)

Lorsque le tableau existe déjà

Si nous essayons d'exécuter le CREATE TABLE ... AS SELECT à nouveau, nous obtenons une erreur, car la table existe déjà.

CREATE TABLE Pets2 AS
(SELECT * FROM Pets);

Résultat :

relation "pets2" already exists

Si vous souhaitez insérer des données dans une table qui existe déjà, utilisez le INSERT INTO... SELECT déclaration. Cela ajoutera les données à toutes les données existantes. Autrement dit, il ajoutera de nouvelles lignes au tableau, tout en conservant les lignes existantes.

Filtrer les résultats

Le SELECT l'instruction peut faire l'habituel SELECT des éléments d'instruction, tels que le filtrage des résultats avec un WHERE clause.

CREATE TABLE Pets3 AS
(SELECT * FROM Pets
WHERE DOB < '2020-06-01');

Dans cet exemple, je filtre les données uniquement pour les animaux dont la date de naissance (DOB) est antérieure au 1er juin 2020.

Sélectionner à partir de plusieurs tableaux

Vous pouvez sélectionner des données dans plusieurs tables, puis faire en sorte que la définition de la table de destination soit basée sur l'ensemble de résultats.

CREATE TABLE PetsTypesOwners AS
(SELECT
    p.PetId,
    p.PetName,
    p.DOB,
    pt.PetTypeId,
    pt.PetType,    
    o.OwnerId,
    o.FirstName,
    o.LastName,
    o.Phone,
    o.Email
FROM Pets p 
INNER JOIN PetTypes pt 
ON p.PetTypeId = pt.PetTypeId 
INNER JOIN Owners o 
ON p.OwnerId = o.OwnerId);

Ici, nous interrogeons trois tables et insérons les résultats dans une table appelée PetsTypesOwners .

Notez que j'ai listé chaque colonne ici parce que je ne voulais pas inclure toutes les colonnes.

Plus précisément, je ne voulais pas doubler les colonnes de clé étrangère/clé primaire. Dans mon cas, les clés étrangères partagent les mêmes noms que leurs homologues de clé primaire dans la table parent, et j'aurais reçu une erreur en raison de la création de noms de colonnes en double dans la table de destination.

Voici ce que je veux dire.

CREATE TABLE PetsTypesOwners2 AS
(SELECT *
FROM Pets p 
INNER JOIN PetTypes pt 
ON p.PetTypeId = pt.PetTypeId 
INNER JOIN Owners o 
ON p.OwnerId = o.OwnerId);

Résultat :

column "pettypeid" specified more than once

Si vos clés étrangères utilisent des noms de colonne différents de ceux des clés primaires, vous vous retrouverez probablement avec une table de destination contenant des colonnes inutiles (une pour la clé primaire, une pour la clé étrangère et chacune contenant les mêmes valeurs).

Si vous voulez vraiment inclure de telles colonnes en double, mais qu'elles partagent le même nom, vous pouvez toujours utiliser des alias pour leur attribuer un nom différent dans la table de destination.

CREATE TABLE PetsTypesOwners2 AS
(SELECT 
    p.PetId, 
    p.OwnerId AS PetOwnerId, 
    p.PetTypeId AS PetPetTypeId,
    p.PetName,
    p.DOB,
    pt.PetTypeId,
    pt.PetType,    
    o.OwnerId,
    o.FirstName,
    o.LastName,
    o.Phone,
    o.Email
FROM Pets p 
INNER JOIN PetTypes pt 
ON p.PetTypeId = pt.PetTypeId 
INNER JOIN Owners o 
ON p.OwnerId = o.OwnerId);

Dans ce cas, j'ai utilisé des alias de colonne pour réaffecter le nom de deux colonnes à PetOwnerId et PetPetTypeId .

Support SGBD

Bien que le CREATE TABLE ... AS SELECT est conforme au standard SQL, elle n'est pas supportée par tous les SGBD. De plus, pour ceux qui le prennent en charge, il existe des variations autour de sa mise en œuvre.

Par conséquent, je vous suggère de consulter la documentation de votre SGBD si vous souhaitez utiliser cette instruction.

Si vous utilisez SQL Server, vous pouvez utiliser le SELECT INTO déclaration, qui fait fondamentalement la même chose.

Il y a aussi le INSERT INTO ... SELECT déclaration prise en charge par de nombreux SGBD. Cette instruction insère les résultats de la requête dans une table existante.