Estou aprendendo PostgreSQL e tentando descobrir como criar uma tabela temporária ou uma WITH
declaraçã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 VALUES
pode ser usado como uma consulta, mas não dá nenhum exemplo; a documentação da VALUES
clá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:
Como posso corrigir a afirmação acima?
Como posso adaptá-lo para ser usado em um
WITH block
?
Desde já, obrigado.
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:
Para realmente criar uma tabela temporária de maneira semelhante, use:
EDIT: Conforme apontado por a_horse_with_no_name, nos documentos afirma que
CREATE TABLE AS...
é funcionalmente semelhante aSELECT INTO ...
, mas que o primeiro é um superconjunto do último e queSELECT 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, aCREATE TABLE
forma deve ser preferida.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.
create table as
precisa de uma instrução select:Você também pode reescrever isso para usar um CTE:
O problema são os tipos de dados. Se você removê-los, a instrução funcionará:
Você pode definir os tipos lançando os valores da primeira linha:
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:
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:que rende:
Ou
JOIN
os valores com outro relacionamento (que novamente pode ser uma tabela regular, visão, etc.), por exemplo:que rende:
Primeiro, sempre use o padronizado
CREATE TABLE AS
,SELECT INTO
como sugerido em outras respostas, é uma sintaxe obsoleta há mais de uma década. Você pode usarCREATE TABLE AS
com um CTEEmbora 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.
Se você precisar escrever uma instrução select, também poderá fazer isso (e não precisa de um CTE).
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,