SQL SELECT INTO
Instrukcja jest rozszerzeniem Sybase, którego można użyć do wstawienia wyników zapytania do tabeli (lub zmiennej, w zależności od DBMS).
W DBMS, takich jak SQL Server i PostgreSQL, SELECT INTO
instrukcja tworzy nową tabelę i wstawia do niej wiersze wynikowe z zapytania.
W MariaDB wstawia zestaw wyników do zmiennej. W Oracle przypisuje wybrane wartości do zmiennych lub kolekcji.
MySQL i SQLite nie obsługują SELECT INTO
w ogóle.
Przykłady w tym artykule wstawiają zestawy wyników do tabeli. W MariaDB i Oracle tabelę docelową można zastąpić nazwą zmiennej (lub nazwą kolekcji, jeśli używasz Oracle).
Przykład podstawowy
Oto podstawowy przykład demonstrujący wybieranie i wstawianie danych do nowej tabeli.
SELECT * INTO Pets2
FROM Pets;
Ten przykład tworzy tabelę o nazwie Pets2
z tą samą definicją tabeli o nazwie Pets
i wstawia wszystkie dane z Pets
w Pets2
.
Możemy to zweryfikować, wybierając zawartość obu tabel.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Wynik:
+---------+-------------+-----------+-----------+------------+ | 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)
Kiedy tabela już istnieje
Jeśli spróbujemy uruchomić SELECT INTO
ponownie, otrzymujemy błąd, ponieważ tabela już istnieje.
SELECT * INTO Pets2
FROM Pets;
Wynik:
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
Jeśli chcesz wstawić dane do tabeli, która już istnieje, użyj INSERT INTO... SELECT
oświadczenie. Spowoduje to dodanie danych do wszelkich istniejących danych. Oznacza to, że doda nowe wiersze do tabeli, zachowując wszystkie istniejące
Filtrowanie wyników
SELECT
instrukcja może wykonać zwykły SELECT
instrukcje, takie jak filtrowanie wyników za pomocą WHERE
klauzula.
SELECT * INTO Pets3
FROM Pets
WHERE DOB < '2020-06-01';
W tym przykładzie filtruję dane tylko do tych zwierząt, które mają datę urodzenia (DOB) sprzed 1 czerwca 2020 r.
Wybieranie z wielu tabel
Możesz wybrać dane z wielu tabel, a następnie ustawić definicję tabeli docelowej na zestawie wyników.
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;
Tutaj wysyłamy zapytanie do trzech tabel i wstawiamy wyniki do tabeli o nazwie PetsTypesOwners
.
Zwróć uwagę, że wymieniłem tutaj każdą kolumnę, ponieważ nie chciałem uwzględniać wszystkich kolumn.
W szczególności nie chciałem podwajać kolumn klucza obcego/klucza podstawowego. W moim przypadku klucze obce mają te same nazwy, co ich odpowiedniki w kluczu podstawowym w tabeli nadrzędnej i otrzymałbym błąd z powodu tworzenia zduplikowanych nazw kolumn w tabeli docelowej.
Oto, co mam na myśli.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Wynik:
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.
Jeśli twoje klucze obce używają innych nazw kolumn niż klucze podstawowe, prawdopodobnie skończysz z tabelą docelową, która zawiera niepotrzebne kolumny (jedna dla klucza podstawowego, jedna dla klucza obcego, a każda zawiera te same wartości).
Jeśli naprawdę chcesz uwzględnić takie zduplikowane kolumny, ale mają one tę samą nazwę, zawsze możesz użyć aliasów, aby przypisać im inną nazwę w tabeli docelowej.
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;
W tym przypadku użyłem aliasów kolumn, aby przypisać nazwy dwóch kolumn do PetOwnerId
i PetPetTypeId
.
WYBIERZ DO Z Widoku
W razie potrzeby możesz również wybrać dane z widoku.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
To wybiera dane z vPetTypeCount
wyświetlić i wstawić go do nowej tabeli o nazwie PetTypeCount
.
Możemy to zweryfikować za pomocą SELECT
oświadczenie.
SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Wynik:
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
Obsługa DBMS
Jak wspomniano, SELECT INTO
Instrukcja jest rozszerzeniem Sybase i nie jest obsługiwana przez wszystkie główne systemy DBMS. Na przykład MySQL i SQLite go nie obsługują.
Ponadto z DBMS, które to obsługują, rzeczywista implementacja różni się nieco w poszczególnych DBMS. Powyższe przykłady zostały wykonane w SQL Server. W MariaDB i Oracle możesz zastąpić tabelę docelową nazwą zmiennej (lub nazwą kolekcji w Oracle).
Jeśli Twój DBMS nie obsługuje SELECT INTO
instrukcja, są szanse, że obsługuje INSERT INTO... SELECT
oświadczenie, więc powinieneś spróbować zamiast tego.