Database
 sql >> Base de Dados >  >> RDS >> Database

SQL CREATE TABLE … AS SELECT Instrução


O SQL CREATE TABLE ... AS SELECT A instrução permite inserir os resultados de uma consulta em uma nova tabela.

Exemplo básico


Aqui está um exemplo básico para demonstrar a seleção e inserção dos dados em uma nova tabela.
CREATE TABLE Pets2 AS
(SELECT * FROM Pets);

Isso cria uma nova tabela chamada Pets2 (com a mesma definição de Pets ) e insere os resultados da consulta nele.

O padrão SQL requer parênteses em torno da cláusula de subconsulta, mas eles podem ser opcionais em seu SGBD (por exemplo, PostgreSQL).

Se selecionarmos ambas as tabelas, podemos ver que ambas têm os mesmos dados.
barney=# SELECT * FROM Pets;
 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    | 
     8 |         2 |       4 | Meow    | 
(8 rows)

barney=# SELECT * FROM Pets2;
 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    | 
     8 |         2 |       4 | Meow    | 
(8 rows)

Quando a tabela já existe


Se tentarmos executar o CREATE TABLE ... AS SELECT declaração novamente, obtemos um erro, devido à tabela já existente.
CREATE TABLE Pets2 AS
(SELECT * FROM Pets);

Resultado:
relation "pets2" already exists

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.
CREATE TABLE Pets3 AS
(SELECT * 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.
CREATE TABLE PetsTypesOwners AS
(SELECT
    p.PetId,
    p.PetName,
    p.DOB,
    pt.PetTypeId,
    pt.PetType,    
    o.OwnerId,
    o.FirstName,
    o.LastName,
    o.Phone,
    o.Email
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.
CREATE TABLE PetsTypesOwners2 AS
(SELECT *
FROM Pets p 
INNER JOIN PetTypes pt 
ON p.PetTypeId = pt.PetTypeId 
INNER JOIN Owners o 
ON p.OwnerId = o.OwnerId);

Resultado:
column "pettypeid" 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.
CREATE TABLE PetsTypesOwners2 AS
(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
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 .

Suporte a DBMS


Embora o CREATE TABLE ... AS SELECT estiver em conformidade com o padrão SQL, ela não é suportada por todos os SGBDs. Além disso, para aqueles que o suportam, existem variações em torno de sua implementação.

Portanto, sugiro verificar com a documentação do seu DBMS se você deseja usar esta instrução.

Se você usa o SQL Server, pode usar o SELECT INTO declaração, que faz basicamente a mesma coisa.

Há também o INSERT INTO ... SELECT declaração que muitos SGBDs suportam. Essa instrução insere os resultados da consulta em uma tabela existente.