Le SQL SELECT INTO
instruction est une extension Sybase qui peut être utilisée pour insérer les résultats d'une requête dans une table (ou une variable, selon le SGBD).
Dans les SGBD tels que SQL Server et PostgreSQL, le SELECT INTO
L'instruction crée une nouvelle table et y insère les lignes résultantes de la requête.
Dans MariaDB, il insère le jeu de résultats dans une variable. Dans Oracle, il affecte les valeurs sélectionnées aux variables ou aux collections.
MySQL et SQLite ne prennent pas en charge le SELECT INTO
déclaration du tout.
Les exemples de cet article insèrent les jeux de résultats dans une table. Dans MariaDB et Oracle, la table de destination peut être remplacée par un nom de variable (ou le nom de la collection si vous utilisez Oracle).
Exemple de base
Voici un exemple de base pour illustrer la sélection et l'insertion des données dans une nouvelle table.
SELECT * INTO Pets2
FROM Pets;
Cet exemple crée une table appelée Pets2
avec la même définition de la table appelée Pets
et insère toutes les données de Pets
dans Pets2
.
Nous pouvons le vérifier en sélectionnant le contenu des deux tables.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Résultat :
+---------+-------------+-----------+-----------+------------+ | 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 | NULL | | 8 | 2 | 4 | Meow | NULL | +---------+-------------+-----------+-----------+------------+ (8 rows affected) +---------+-------------+-----------+-----------+------------+ | 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 | NULL | | 8 | 2 | 4 | Meow | NULL | +---------+-------------+-----------+-----------+------------+ (8 rows affected)
Lorsque le tableau existe déjà
Si nous essayons d'exécuter le SELECT INTO
à nouveau, nous obtenons une erreur, car la table existe déjà.
SELECT * INTO Pets2
FROM Pets;
Résultat :
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
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. C'est-à-dire qu'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.
SELECT * INTO Pets3
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.
SELECT
p.PetId,
p.PetName,
p.DOB,
pt.PetTypeId,
pt.PetType,
o.OwnerId,
o.FirstName,
o.LastName,
o.Phone,
o.Email
INTO PetsTypesOwners
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.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Résultat :
Msg 2705, Level 16, State 3, Line 1 Column names in each table must be unique. Column name 'PetTypeId' in table 'PetsTypesOwners2' is 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.
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
INTO PetsTypesOwners3
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
.
SELECT INTO à partir d'une vue
Vous pouvez également sélectionner des données à partir d'une vue si nécessaire.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
Cela sélectionne les données de vPetTypeCount
afficher et l'insère dans une nouvelle table appelée PetTypeCount
.
Nous pouvons le vérifier avec un SELECT
déclaration.
SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Résultat :
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
Support SGBD
Comme mentionné, le SELECT INTO
est une extension Sybase et n'est pas prise en charge par tous les principaux SGBD. Par exemple, MySQL et SQLite ne le supportent pas.
De plus, parmi les SGBD qui le prennent en charge, l'implémentation réelle varie quelque peu d'un SGBD à l'autre. Les exemples ci-dessus ont été réalisés dans SQL Server. Dans MariaDB et Oracle, vous pouvez remplacer la table de destination par un nom de variable (ou un nom de collection dans Oracle).
Si votre SGBD ne prend pas en charge le SELECT INTO
, il y a de fortes chances qu'il supporte le INSERT INTO... SELECT
déclaration, vous devriez donc essayer cela à la place.