CRIAR TABELA AS vs SELECT INTO

16

O PostgreSQL suporta CREATE TABLE ASe SELECT INTOquando uso os dois?

CREATE TABLE AS - definir uma nova tabela a partir dos resultados de uma consulta

CREATE TABLE AScria uma tabela e a preenche com dados calculados por um SELECTcomando. As colunas da tabela têm os nomes e tipos de dados associados às colunas de saída do SELECT(exceto que você pode substituir os nomes das colunas, fornecendo uma lista explícita de novos nomes de colunas).

CREATE TABLE AStem alguma semelhança com a criação de uma exibição, mas é realmente bem diferente: cria uma nova tabela e avalia a consulta apenas uma vez para preencher a nova tabela inicialmente. A nova tabela não rastreará alterações subseqüentes nas tabelas de origem da consulta. Por outro lado, uma visão reavalia sua SELECTdeclaração de definição sempre que é consultada.

E depois.

SELECT INTO - definir uma nova tabela a partir dos resultados de uma consulta

SELECT INTOcria uma nova tabela e a preenche com dados calculados por uma consulta. Os dados não são retornados ao cliente, como é normal SELECT. As colunas da nova tabela têm os nomes e tipos de dados associados às colunas de saída do SELECT.

Evan Carroll
fonte

Respostas:

15

Sem a explicação, sempre use CREATE TABLE ASsem exceção. Na parte inferior de cada uma das notas, isso é esclarecido,

Notas para SELECT INTO,

CREATE TABLE ASé funcionalmente semelhante a SELECT INTO. CREATE TABLE ASé a sintaxe recomendada, pois essa forma de SELECT INTOnão está disponível no ECPG ou PL / pgSQL, porque eles interpretam a cláusula INTO de maneira diferente. Além disso, CREATE TABLE ASoferece um superconjunto da funcionalidade fornecida pelo SELECT INTO.

Notas para CREATE TABLE AS,

Esse comando é funcionalmente semelhante a SELECT INTO, mas é preferível, pois é menos provável que seja confundido com outros usos da SELECT INTOsintaxe. Além disso, CREATE TABLE ASoferece um superconjunto da funcionalidade oferecida pelo SELECT INTO.

Também na seção Compatibilidade dos documentos, SELECT INTOele vai ainda mais longe,

O padrão SQL usa SELECT INTOpara representar a seleção de valores em variáveis ​​escalares de um programa host, em vez de criar uma nova tabela. Este é realmente o uso encontrado no ECPG (consulte o Capítulo 34) e no PL / pgSQL (consulte o Capítulo 41). O uso do PostgreSQL SELECT INTOpara representar a criação de tabelas é histórico. É melhor usar CREATE TABLE ASpara esse fim em novo código.

Então nós temos,

  1. O PostgreSQL acha confuso porque SELECT INTOfaz outras coisas em contextos disponíveis apenas no PL / pgSQL e ECPG.
  2. CREATE TABLEsuporta mais funcionalidade (presumo que eles estejam se referindo a WITH OIDS, e TABLESPACE, IF NOT EXISTS).
  3. SELECT INTO para a criação da tabela está "obsoleta".

Como uma observação lateral, a sintaxe para um CTAS com um CTE pode parecer um pouco estranha. , e também SELECT INTO pode ser algum tipo de retenção sobre os QUELRETRIEVE INTO . QUEL foi o antecessor do SQL, usado pelo antecessor do PostgreSQL (INGRES).

Evan Carroll
fonte
1

Notei outra coisa que faltava na resposta aceita. O uso CREATE TABLE ASpreserva o atributo nulo de cada coluna que parece ser ignorado por SELECT INTO.

Apenas com base nisso, eu recomendo CREATE TABLE AS. Um caso de uso comum para ambas as instruções é carregar dados de uma consulta de execução longa em uma tabela sem bloquear essa tabela pela duração da sua consulta. Você cria uma tabela temporária usando um dos comandos acima, coloca os resultados da consulta de longa execução e insere esses resultados na tabela original. Preservar o atributo anulável em sua tabela temporária reduz as chances de sua segunda inserção falhar.

Testei isso no PG 11, talvez um recurso mais recente, já que essa pergunta foi respondida.

shrumm
fonte
Uma consulta de longa duração não bloqueia nenhuma tabela. Portanto, a motivação para usar o CTAS por esse motivo é inútil
a_horse_with_no_name 18/08/19