AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 86724
Accepted
tinlyx
tinlyx
Asked: 2014-12-22 11:44:18 +0800 CST2014-12-22 11:44:18 +0800 CST 2014-12-22 11:44:18 +0800 CST

Como criar uma tabela temporária usando VALUES no PostgreSQL

  • 772

Estou aprendendo PostgreSQL e tentando descobrir como criar uma tabela temporária ou uma WITHdeclaração que possa ser usada no lugar de uma tabela regular, para fins de depuração.

Eu olhei para a documentação para CREATE TABLE e diz que VALUESpode ser usado como uma consulta, mas não dá nenhum exemplo; a documentação da VALUEScláusula vinculada a ela também não tem um exemplo?

Então, eu escrevi um teste simples da seguinte forma:

DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup (
  key integer,
  val numeric
) AS
VALUES (0,-99999), (1,100);

Mas o PostgreSQL (9.3) está reclamando

erro de sintaxe em ou próximo a "AS"

Minhas perguntas são:

  1. Como posso corrigir a afirmação acima?

  2. Como posso adaptá-lo para ser usado em um WITH block?

Desde já, obrigado.

postgresql syntax
  • 6 6 respostas
  • 137660 Views

6 respostas

  • Voted
  1. Best Answer
    John Powell
    2014-12-22T13:49:33+08:002014-12-22T13:49:33+08:00

    EDIT: estou deixando a resposta original aceita como está, mas observe que a edição abaixo, conforme sugerido por a_horse_with_no_name , é o método preferido para criar uma tabela temporária usando VALUES.

    Se você quiser apenas selecionar alguns valores, em vez de apenas criar uma tabela e inserir nela, você pode fazer algo como:

    WITH  vals (k,v) AS (VALUES (0,-9999), (1, 100)) 
    SELECT * FROM vals;
    

    Para realmente criar uma tabela temporária de maneira semelhante, use:

    WITH  vals (k,v) AS (VALUES (0,-9999), (1, 100)) 
    SELECT * INTO temporary table temp_table FROM vals;
    

    EDIT: Conforme apontado por a_horse_with_no_name, nos documentos afirma que CREATE TABLE AS...é funcionalmente semelhante a SELECT INTO ..., mas que o primeiro é um superconjunto do último e que SELECT INTOé usado em plpgslq para atribuir um valor a uma variável temporária - então falharia em Aquele caso. Portanto, enquanto os exemplos acima são válidos para SQL simples, a CREATE TABLEforma deve ser preferida.

    CREATE TEMP TABLE temp_table AS                                     
    WITH t (k, v) AS (
     VALUES
     (0::int,-99999::numeric), 
     (1::int,100::numeric)
    )
    SELECT * FROM t;
    

    Observe também nos comentários de a_horse_with_no_name e na pergunta original do OP, isso inclui uma conversão para os tipos de dados corretos dentro da lista de valores e usa uma instrução CTE (WITH).

    Além disso, como apontado na resposta de Evan Carrol, no Postgres anterior à versão 12, uma consulta CTE é sempre uma cerca de otimização , ou seja, o CTE é sempre materializado. Há muitas boas razões para usar CTEs, mas pode haver um impacto significativo no desempenho, se não for usado com cuidado. Há, no entanto, muitas instâncias em que a cerca de otimização pode realmente melhorar o desempenho, portanto, isso é algo para se estar ciente, não para evitar cegamente.

    • 79
  2. a_horse_with_no_name
    2014-12-22T13:59:57+08:002014-12-22T13:59:57+08:00

    create table asprecisa de uma instrução select:

    DROP TABLE IF EXISTS lookup;
    CREATE TEMP TABLE lookup 
    as 
    select *
    from (
       VALUES 
        (0::int,-99999::numeric), 
        (1::int, 100::numeric)
    ) as t (key, value);
    

    Você também pode reescrever isso para usar um CTE:

    create temp table lookup 
    as 
    with t (key, value) as (
      values 
        (0::int,-99999::numeric), 
        (1::int,100::numeric)
    )
    select * from t;
    
    • 32
  3. ypercubeᵀᴹ
    2017-05-19T04:52:48+08:002017-05-19T04:52:48+08:00

    O problema são os tipos de dados. Se você removê-los, a instrução funcionará:

    CREATE TEMP TABLE lookup
      (key, val) AS
    VALUES 
      (0, -99999), 
      (1, 100) ;
    

    Você pode definir os tipos lançando os valores da primeira linha:

    CREATE TEMP TABLE lookup 
      (key, val) AS
    VALUES 
      (0::bigint, -99999::int), 
      (1, 100) ;
    
    • 16
  4. isapir
    2017-10-21T08:42:10+08:002017-10-21T08:42:10+08:00

    Você realmente não precisa criar uma tabela nem usar um CTE, se tudo que você precisa é usar alguns valores em suas consultas. Você pode inline-los:

    SELECT  *
    FROM    (VALUES(0::INT, -99999::NUMERIC), (1, 100)) AS lookup(key, val)
    

    Então você pode obter um produto cartesiano com um CROSS JOIN(onde a outra relação pode ser, é claro, uma tabela regular, visualização, etc.). por exemplo:

    SELECT  *
    FROM    (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
           ,(VALUES('Red'), ('White'), ('Blue')) AS colors(color);
    

    que rende:

    key |val    |color |
    ----|-------|------|
    0   |-99999 |Red   |
    1   |100    |Red   |
    0   |-99999 |White |
    1   |100    |White |
    0   |-99999 |Blue  |
    1   |100    |Blue  |
    

    Ou JOINos valores com outro relacionamento (que novamente pode ser uma tabela regular, visão, etc.), por exemplo:

    SELECT  *
    FROM    (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
      JOIN  (VALUES('Red', 1), ('White', 0), ('Blue', 1)) AS colors(color, lookup_key)
              ON colors.lookup_key = lookup.key;
    

    que rende:

    key |val    |color |lookup_key |
    ----|-------|------|-----------|
    1   |100    |Red   |1          |
    0   |-99999 |White |0          |
    1   |100    |Blue  |1          |
    
    • 9
  5. Evan Carroll
    2018-03-18T23:51:03+08:002018-03-18T23:51:03+08:00

    Primeiro, sempre use o padronizado CREATE TABLE AS, SELECT INTOcomo sugerido em outras respostas, é uma sintaxe obsoleta há mais de uma década. Você pode usarCREATE TABLE AS com um CTE

    Embora muitas respostas aqui estejam sugerindo o uso de um CTE, isso não é preferível. Na verdade, é provável que seja um pouco mais lento. Basta envolvê-lo como uma mesa.

    DROP TABLE IF EXISTS lookup;
    
    CREATE TEMP TABLE lookup(key, value) AS
      VALUES
      (0::int,-99999::numeric),
      (1,100);
    

    Se você precisar escrever uma instrução select, também poderá fazer isso (e não precisa de um CTE).

    CREATE TEMP TABLE lookup(key, value) AS
      SELECT key::int, value::numeric
      FROM ( VALUES
        (0::int,-99999::numeric),
        (1,100)
      ) AS t(key, value);
    

    Um CTE no PostgreSQL força a materialização. É uma cerca de otimização. Por esse motivo, geralmente não é uma boa ideia usá-los em qualquer lugar, exceto quando você entende os custos e sabe que isso pode fornecer uma melhoria de desempenho. Você pode ver a lentidão aqui, por exemplo,

    \timing
    CREATE TABLE foo AS
      SELECT * FROM generate_series(1,1e7);
    Time: 5699.070 ms
    
    CREATE TABLE foo AS
      WITH t AS ( SELECT * FROM generate_series(1,1e7) ) 
      SELECT * FROM t;
    Time: 6484.516 ms
    
    • 4
  6. caub
    2017-05-19T04:04:48+08:002017-05-19T04:04:48+08:00
    WITH u AS (
        SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS account (id,name)
    )
    SELECT id, name, length(name) from u;
    
    • -2

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve