tin*_*lyx 54 postgresql syntax
我正在学习 PostgreSQL 并试图弄清楚如何创建一个临时表或一个WITH可以用来代替常规表的声明,以用于调试目的。
我查看了CREATE TABLE的文档,它说VALUES可以用作查询,但没有给出示例;VALUES其中链接的条款的文档也没有示例?
所以,我写了一个简单的测试如下:
DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup (
key integer,
val numeric
) AS
VALUES (0,-99999), (1,100);
Run Code Online (Sandbox Code Playgroud)
但是 PostgreSQL (9.3) 抱怨
“AS”处或附近的语法错误
我的问题是:
我怎样才能修正上面的说法?
我如何调整它以用于WITH block?
提前致谢。
Joh*_*ell 68
编辑:我将保留原来接受的答案,但请注意,下面的编辑,如a_horse_with_no_name所建议的,是使用 VALUES 创建临时表的首选方法。
如果您只想从某些值中进行选择,而不仅仅是创建一个表并插入其中,您可以执行以下操作:
WITH vals (k,v) AS (VALUES (0,-9999), (1, 100))
SELECT * FROM vals;
Run Code Online (Sandbox Code Playgroud)
要以类似的方式实际创建临时表,请使用:
WITH vals (k,v) AS (VALUES (0,-9999), (1, 100))
SELECT * INTO temporary table temp_table FROM vals;
Run Code Online (Sandbox Code Playgroud)
编辑:正如 a_horse_with_no_name 所指出的,在文档中它指出它CREATE TABLE AS...在功能上类似于SELECT INTO ...,但前者是后者的超集,SELECT INTO在 plpgslq 中用于为临时变量赋值——因此它会失败那种情况。因此,虽然上述示例对普通 SQL 有效,但CREATE TABLE应首选该形式。
CREATE TEMP TABLE temp_table AS
WITH t (k, v) AS (
VALUES
(0::int,-99999::numeric),
(1::int,100::numeric)
)
SELECT * FROM t;
Run Code Online (Sandbox Code Playgroud)
请注意,同样来自 a_horse_with_no_name 的评论,以及在 OP 的原始问题中,这包括对值列表中正确数据类型的强制转换,并使用 CTE (WITH) 语句。
此外,正如 Evan Carrol 的回答中所指出的,在 12 版之前的 Postgres 中,CTE 查询始终是优化栅栏,即 CTE 始终是物化的。使用 CTE 有很多很好的理由,但如果不小心使用,可能会对性能造成相当大的影响。然而,在很多情况下,优化栅栏实际上可以提高性能,所以这是需要注意的,而不是盲目地避免。
a_h*_*ame 31
create table as 需要一个选择语句:
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);
Run Code Online (Sandbox Code Playgroud)
您还可以重新编写它以使用 CTE:
create temp table lookup
as
with t (key, value) as (
values
(0::int,-99999::numeric),
(1::int,100::numeric)
)
select * from t;
Run Code Online (Sandbox Code Playgroud)
ype*_*eᵀᴹ 15
问题是数据类型。如果您删除它们,该语句将起作用:
CREATE TEMP TABLE lookup
(key, val) AS
VALUES
(0, -99999),
(1, 100) ;
Run Code Online (Sandbox Code Playgroud)
您可以通过转换第一行的值来定义类型:
CREATE TEMP TABLE lookup
(key, val) AS
VALUES
(0::bigint, -99999::int),
(1, 100) ;
Run Code Online (Sandbox Code Playgroud)
如果您只需要在查询中使用一些值,您就真的不需要创建表或使用 CTE。您可以内联它们:
SELECT *
FROM (VALUES(0::INT, -99999::NUMERIC), (1, 100)) AS lookup(key, val)
Run Code Online (Sandbox Code Playgroud)
然后你可以得到一个笛卡尔积CROSS JOIN(当然,其他关系可以是一个普通的表、视图等)。例如:
SELECT *
FROM (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
,(VALUES('Red'), ('White'), ('Blue')) AS colors(color);
Run Code Online (Sandbox Code Playgroud)
产生:
key |val |color |
----|-------|------|
0 |-99999 |Red |
1 |100 |Red |
0 |-99999 |White |
1 |100 |White |
0 |-99999 |Blue |
1 |100 |Blue |
Run Code Online (Sandbox Code Playgroud)
或者JOIN具有另一种关系的值(也可以是常规表、视图等),例如:
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;
Run Code Online (Sandbox Code Playgroud)
产生:
key |val |color |lookup_key |
----|-------|------|-----------|
1 |100 |Red |1 |
0 |-99999 |White |0 |
1 |100 |Blue |1 |
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
116371 次 |
| 最近记录: |