O SQL
SELECT INTO
instrução é uma extensão do Sybase que pode ser usada para inserir os resultados de uma consulta em uma tabela (ou uma variável, dependendo do DBMS). Em SGBDs como SQL Server e PostgreSQL, o
SELECT INTO
A instrução cria uma nova tabela e insere nela as linhas resultantes da consulta. No MariaDB ele insere o conjunto de resultados em uma variável. No Oracle, ele atribui os valores selecionados a variáveis ou coleções.
MySQL e SQLite não suportam o
SELECT INTO
declaração em tudo. Os exemplos neste artigo inserem os conjuntos de resultados em uma tabela. No MariaDB e Oracle, a tabela de destino pode ser substituída por um nome de variável (ou o nome da coleção se você estiver usando Oracle).
Exemplo básico
Aqui está um exemplo básico para demonstrar a seleção e inserção dos dados em uma nova tabela.
SELECT * INTO Pets2
FROM Pets;
Este exemplo cria uma tabela chamada
Pets2
com a mesma definição da tabela chamada Pets
e insere todos os dados de Pets
em Pets2
. Podemos verificar isso selecionando o conteúdo de ambas as tabelas.
SELECT * FROM Pets;
SELECT * FROM Pets2;
Resultado:
+---------+-------------+-----------+-----------+------------+ | 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 a tabela já existe
Se tentarmos executar o
SELECT INTO
declaração novamente, obtemos um erro, devido à tabela já existente. SELECT * INTO Pets2
FROM Pets;
Resultado:
Msg 2714, Level 16, State 6, Line 1 There is already an object named 'Pets2' in the database.
Se você deseja inserir dados em uma tabela que já existe, use o
INSERT INTO... SELECT
demonstração. Isso anexará os dados a quaisquer dados existentes. Ou seja, ele adicionará novas linhas à tabela, mantendo todas as linhas existentes Filtrando os resultados
O
SELECT
pode fazer o usual SELECT
coisas de instrução, como filtrar os resultados com um WHERE
cláusula. SELECT * INTO Pets3
FROM Pets
WHERE DOB < '2020-06-01';
Neste exemplo, filtrei os dados apenas para os animais de estimação que têm uma data de nascimento (DOB) anterior a 1º de junho de 2020.
Seleção de várias tabelas
Você pode selecionar dados de várias tabelas e fazer com que a definição da tabela de destino seja baseada no conjunto de resultados.
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;
Aqui, consultamos três tabelas e inserimos os resultados em uma tabela chamada
PetsTypesOwners
. Observe que listei cada coluna aqui porque não queria incluir todas as colunas.
Especificamente, eu não queria dobrar as colunas de chave estrangeira/chave primária. No meu caso, as chaves estrangeiras compartilham os mesmos nomes que suas contrapartes de chave primária na tabela pai e eu teria recebido um erro devido à criação de nomes de coluna duplicados na tabela de destino.
Aqui está o que quero dizer.
SELECT *
INTO PetsTypesOwners2
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId
INNER JOIN Owners o
ON p.OwnerId = o.OwnerId;
Resultado:
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 suas chaves estrangeiras usarem nomes de coluna diferentes das chaves primárias, você provavelmente terminará com uma tabela de destino que contém colunas desnecessárias (uma para a chave primária, uma para a chave estrangeira e cada uma contendo os mesmos valores).
Se você realmente deseja incluir essas colunas duplicadas, mas elas compartilham o mesmo nome, você sempre pode usar aliases para atribuí-las com um nome diferente na tabela de destino.
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;
Nesse caso, usei aliases de coluna para reatribuir o nome de duas colunas a
PetOwnerId
e PetPetTypeId
. SELECT INTO de uma visualização
Você também pode selecionar dados de uma exibição, se necessário.
SELECT * INTO PetTypeCount
FROM vPetTypeCount;
Isso seleciona dados do
vPetTypeCount
view e a insere em uma nova tabela chamada PetTypeCount
. Podemos verificar isso com um
SELECT
demonstração. SELECT * FROM vPetTypeCount;
SELECT * FROM PetTypeCount;
Resultado:
+-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected) +-----------+---------+ | PetType | Count | |-----------+---------| | Bird | 1 | | Cat | 3 | | Dog | 4 | +-----------+---------+ (3 rows affected)
Suporte a DBMS
Como mencionado, o
SELECT INTO
A instrução é uma extensão do Sybase e não é suportada por todos os principais DBMSs. Por exemplo, MySQL e SQLite não o suportam. Além disso, dos DBMSs que o suportam, a implementação real varia um pouco entre os DBMS. Os exemplos acima foram feitos no SQL Server. No MariaDB e no Oracle, você pode substituir a tabela de destino por um nome de variável (ou nome de coleção no Oracle).
Se o seu DBMS não suportar o
SELECT INTO
, é provável que ele suporte o INSERT INTO... SELECT
declaração, então você deve tentar isso em vez disso.