SQL'en SELECT INTO
statement er en Sybase-udvidelse, der kan bruges til at indsætte resultaterne af en forespørgsel i en tabel (eller en variabel, afhængigt af DBMS).
I DBMS'er såsom SQL Server og PostgreSQL er SELECT INTO
sætning opretter en ny tabel og indsætter de resulterende rækker fra forespørgslen i den.
I MariaDB indsætter den resultatsættet i en variabel. I Oracle tildeler den de valgte værdier til variabler eller samlinger.
MySQL og SQLite understøtter ikke SELECT INTO
erklæring overhovedet.
Eksemplerne i denne artikel indsætter resultatsættene i en tabel. I MariaDB og Oracle kan destinationstabellen erstattes af et variabelnavn (eller samlingsnavnet, hvis du bruger Oracle).
Grundlæggende eksempel
Her er et grundlæggende eksempel til at demonstrere valg og indsættelse af data i en ny tabel.
SELECT * INTO Pets2
FROM Pets;
Dette eksempel opretter en tabel kaldet Pets2
med samme definition af tabellen kaldet Pets
og indsætter alle data fra Pets
ind i Pets2
.
Vi kan bekræfte dette ved at vælge indholdet af begge tabeller.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Resultat:
+---------+-------------+-----------+-----------+------------+ | 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)
Når tabellen allerede eksisterer
Hvis vi prøver at køre SELECT INTO
sætning igen, får vi en fejl, på grund af tabellen allerede eksisterende.
SELECT * INTO Pets2
FROM Pets;
Resultat:
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
Hvis du vil indsætte data i en tabel, der allerede eksisterer, skal du bruge INSERT INTO... SELECT
udmelding. Dette vil tilføje dataene til alle eksisterende data. Det vil sige, at den tilføjer nye rækker til tabellen, mens de bevarer eksisterende rækker
Filtrering af resultaterne
SELECT
sætning kan gøre den sædvanlige SELECT
sætningsting, såsom at filtrere resultaterne med en WHERE
klausul.
SELECT * INTO Pets3
FROM Pets
WHERE DOB < '2020-06-01';
I dette eksempel filtrerer jeg dataene til kun de kæledyr, der har en fødselsdato (DOB) fra før den 1. juni 2020.
Vælg fra flere tabeller
Du kan vælge data fra flere tabeller og derefter få destinationstabellens definition baseret på resultatsættet.
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;
Her forespørger vi tre tabeller og indsætter resultaterne i en tabel kaldet PetsTypesOwners
.
Bemærk, at jeg har angivet hver kolonne her, fordi jeg ikke ønskede at inkludere alle kolonner.
Specifikt ønskede jeg ikke at fordoble kolonnerne med fremmednøgle/primærnøgle. I mit tilfælde deler de fremmede nøgler de samme navne som deres primære nøglemodstykker i den overordnede tabel, og jeg ville have modtaget en fejl på grund af, at duplikerede kolonnenavne blev oprettet i destinationstabellen.
Her er hvad jeg mener.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Resultat:
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.
Hvis dine fremmednøgler bruger forskellige kolonnenavne end de primære nøgler, vil du sandsynligvis ende med en destinationstabel, der indeholder unødvendige kolonner (en for den primære nøgle, en for den fremmede nøgle, og hver indeholder de samme værdier).
Hvis du virkelig ønsker at inkludere sådanne duplikerede kolonner, men de deler det samme navn, kan du altid bruge aliaser til at tildele dem et andet navn i destinationstabellen.
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;
I dette tilfælde brugte jeg kolonnealiasser til at omtildele navnet på to kolonner til PetOwnerId
og PetPetTypeId
.
VÆLG IND fra en visning
Du kan også vælge data fra en visning, hvis det er nødvendigt.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
Dette vælger data fra vPetTypeCount
se og indsætter det i en ny tabel kaldet PetTypeCount
.
Vi kan bekræfte dette med en SELECT
erklæring.
SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Resultat:
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
DBMS-understøttelse
Som nævnt er SELECT INTO
statement er en Sybase-udvidelse, og den understøttes ikke af alle større DBMS'er. For eksempel understøtter MySQL og SQLite det ikke.
Ud af de DBMS'er, der understøtter det, varierer den faktiske implementering også noget mellem DBMS. Ovenstående eksempler blev udført i SQL Server. I MariaDB og Oracle kan du erstatte destinationstabellen med et variabelnavn (eller samlingsnavn i Oracle).
Hvis dit DBMS ikke understøtter SELECT INTO
sætning, sandsynligvis understøtter den INSERT INTO... SELECT
sætning, så du bør prøve det i stedet.