SQL SELECT INTO
statement je rozšíření Sybase, které lze použít k vložení výsledků dotazu do tabulky (nebo proměnné, v závislosti na DBMS).
V DBMS, jako je SQL Server a PostgreSQL, SELECT INTO
příkaz vytvoří novou tabulku a vloží do ní výsledné řádky z dotazu.
V MariaDB vloží sadu výsledků do proměnné. V Oracle přiřazuje vybrané hodnoty proměnným nebo kolekcím.
MySQL a SQLite nepodporují SELECT INTO
prohlášení vůbec.
Příklady v tomto článku vloží sady výsledků do tabulky. V MariaDB a Oracle lze cílovou tabulku nahradit názvem proměnné (nebo názvem kolekce, pokud používáte Oracle).
Základní příklad
Zde je základní příklad, který demonstruje výběr a vkládání dat do nové tabulky.
SELECT * INTO Pets2
FROM Pets;
Tento příklad vytvoří tabulku s názvem Pets2
se stejnou definicí tabulky nazvané Pets
a vloží všechna data z Pets
do Pets2
.
Můžeme to ověřit výběrem obsahu obou tabulek.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Výsledek:
+---------+-------------+-----------+-----------+------------+ | 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)
Když tabulka již existuje
Pokud se pokusíme spustit SELECT INTO
znovu, dostaneme chybu, protože tabulka již existuje.
SELECT * INTO Pets2
FROM Pets;
Výsledek:
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
Pokud chcete vložit data do tabulky, která již existuje, použijte INSERT INTO... SELECT
prohlášení. Tím se data připojí ke všem existujícím datům. To znamená, že do tabulky přidá nové řádky a všechny existující řádky zachová
Filtrování výsledků
SELECT
příkaz může provést obvyklý SELECT
příkazy, jako je filtrování výsledků pomocí WHERE
doložka.
SELECT * INTO Pets3
FROM Pets
WHERE DOB < '2020-06-01';
V tomto příkladu filtruji data pouze na ta domácí zvířata, která mají datum narození (DOB) před 1. červnem 2020.
Výběr z více tabulek
Můžete vybrat data z více tabulek a poté nechat, aby byla definice cílové tabulky založena na výsledné sadě.
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;
Zde dotazujeme tři tabulky a výsledky vložíme do tabulky nazvané PetsTypesOwners
.
Všimněte si, že jsem zde uvedl každý sloupec, protože jsem nechtěl zahrnout všechny sloupce.
Konkrétně jsem nechtěl zdvojnásobit sloupce cizí klíč / primární klíč. V mém případě sdílejí cizí klíče stejná jména jako jejich protějšky primárního klíče v nadřazené tabulce a já bych obdržel chybu kvůli vytváření duplicitních názvů sloupců v cílové tabulce.
Tady je to, co mám na mysli.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Výsledek:
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.
Pokud vaše cizí klíče používají jiné názvy sloupců než primární klíče, pravděpodobně skončíte s cílovou tabulkou, která obsahuje zbytečné sloupce (jeden pro primární klíč, jeden pro cizí klíč a každý obsahuje stejné hodnoty).
Pokud opravdu chcete zahrnout takové duplicitní sloupce, ale mají stejný název, můžete jim vždy pomocí aliasů přiřadit v cílové tabulce jiný název.
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;
V tomto případě jsem použil aliasy sloupců k přeřazení názvu dvou sloupců na PetOwnerId
a PetPetTypeId
.
VYBRAT DO Z pohledu
V případě potřeby můžete také vybrat data z pohledu.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
Tím se vyberou data z vPetTypeCount
zobrazit a vloží jej do nové tabulky s názvem PetTypeCount
.
Můžeme to ověřit pomocí SELECT
prohlášení.
SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Výsledek:
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
Podpora DBMS
Jak již bylo zmíněno, SELECT INTO
statement je rozšíření Sybase a není podporováno všemi hlavními DBMS. Například MySQL a SQLite to nepodporují.
Také z DBMS, které to podporují, se skutečná implementace mezi DBMS poněkud liší. Výše uvedené příklady byly provedeny na serveru SQL Server. V MariaDB a Oracle můžete nahradit cílovou tabulku názvem proměnné (nebo názvem kolekce v Oracle).
Pokud váš DBMS nepodporuje SELECT INTO
je pravděpodobné, že podporuje INSERT INTO... SELECT
prohlášení, takže byste to měli místo toho zkusit.