L'SQL SELECT INTO
istruzione è un'estensione Sybase che può essere utilizzata per inserire i risultati di una query in una tabella (o una variabile, a seconda del DBMS).
Nei DBMS come SQL Server e PostgreSQL, SELECT INTO
istruzione crea una nuova tabella e inserisce le righe risultanti dalla query in essa.
In MariaDB inserisce il set di risultati in una variabile. In Oracle, assegna i valori selezionati a variabili o raccolte.
MySQL e SQLite non supportano SELECT INTO
dichiarazione a tutti.
Gli esempi in questo articolo inseriscono i set di risultati in una tabella. In MariaDB e Oracle, la tabella di destinazione può essere sostituita da un nome di variabile (o dal nome della raccolta se stai utilizzando Oracle).
Esempio di base
Ecco un esempio di base per dimostrare la selezione e l'inserimento dei dati in una nuova tabella.
SELECT * INTO Pets2
FROM Pets;
Questo esempio crea una tabella chiamata Pets2
con la stessa definizione della tabella denominata Pets
e inserisce tutti i dati da Pets
in Pets2
.
Possiamo verificarlo selezionando il contenuto di entrambe le tabelle.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Risultato:
+---------+-------------+-----------+-----------+------------+ | 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)
Quando la tabella esiste già
Se proviamo a eseguire SELECT INTO
di nuovo, otteniamo un errore, dovuto alla tabella già esistente.
SELECT * INTO Pets2
FROM Pets;
Risultato:
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
Se vuoi inserire dati in una tabella già esistente, usa INSERT INTO... SELECT
dichiarazione. Questo aggiungerà i dati a tutti i dati esistenti. Cioè, aggiungerà nuove righe alla tabella, mantenendo tutte le righe esistenti
Filtraggio dei risultati
Il SELECT
l'istruzione può fare il solito SELECT
materiale di istruzione, come filtrare i risultati con un WHERE
clausola.
SELECT * INTO Pets3
FROM Pets
WHERE DOB < '2020-06-01';
In questo esempio, filtro i dati solo per quegli animali domestici che hanno una data di nascita (DOB) precedente al 1 giugno 2020.
Selezione da più tabelle
Puoi selezionare i dati da più tabelle, quindi fare in modo che la definizione della tabella di destinazione sia basata sul set di risultati.
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;
Qui, interroghiamo tre tabelle e inseriamo i risultati in una tabella chiamata PetsTypesOwners
.
Nota che ho elencato ogni colonna qui perché non volevo includere tutte le colonne.
In particolare, non volevo raddoppiare le colonne chiave esterna/chiave primaria. Nel mio caso, le chiavi esterne condividono gli stessi nomi delle loro controparti di chiave primaria nella tabella padre e avrei ricevuto un errore a causa della creazione di nomi di colonna duplicati nella tabella di destinazione.
Ecco cosa intendo.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Risultato:
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.
Se le tue chiavi esterne utilizzano nomi di colonna diversi rispetto alle chiavi primarie, probabilmente ti ritroverai con una tabella di destinazione che contiene colonne non necessarie (una per la chiave primaria, una per la chiave esterna e ciascuna contenente gli stessi valori).
Se vuoi davvero includere tali colonne duplicate, ma condividono lo stesso nome, puoi sempre utilizzare gli alias per assegnarle con un nome diverso nella tabella di destinazione.
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;
In questo caso ho utilizzato gli alias di colonna per riassegnare il nome di due colonne a PetOwnerId
e PetPetTypeId
.
SELEZIONA IN da una vista
Se necessario, puoi anche selezionare i dati da una vista.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
Questo seleziona i dati da vPetTypeCount
visualizza e lo inserisce in una nuova tabella denominata PetTypeCount
.
Possiamo verificarlo con un SELECT
dichiarazione.
SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Risultato:
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
Supporto DBMS
Come accennato, il SELECT INTO
è un'estensione Sybase e non è supportata da tutti i principali DBMS. Ad esempio, MySQL e SQLite non lo supportano.
Inoltre, al di fuori dei DBMS che lo supportano, l'implementazione effettiva varia leggermente tra i DBMS. Gli esempi precedenti sono stati eseguiti in SQL Server. In MariaDB e Oracle puoi sostituire la tabella di destinazione con un nome di variabile (o nome di raccolta in Oracle).
Se il tuo DBMS non supporta il SELECT INTO
istruzione, è probabile che supporti INSERT INTO... SELECT
dichiarazione, quindi dovresti provarlo invece.