PostgreSQL을 배우고 WITH
디버깅을 위해 임시 테이블 또는 일반 테이블 대신 사용할 수 있는 선언 을 만드는 방법을 알아 내려고 노력 중 입니다.
나는 설명서 보았다 표를 작성 하고 그것을 말한다 VALUES
쿼리로 사용할 수 있지만 예를주지 않는다; 그에 VALUES
연결된 조항에 대한 문서도 예제가 없습니까?
그래서 다음과 같이 간단한 테스트를 작성했습니다.
DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup (
key integer,
val numeric
) AS
VALUES (0,-99999), (1,100);
그러나 PostgreSQL (9.3)은 다음에 대해 불평하고 있습니다.
“AS”근처 또는 근처의 구문 오류
내 질문은 :
-
위의 진술을 어떻게 고칠 수 있습니까?
-
에 사용되도록 어떻게 조정할 수
WITH block
있습니까?
미리 감사드립니다.
답변
편집 : 원래 허용 된 답변을 그대로두고 있지만 a_horse_with_no_name에서 제안한 아래 편집은 VALUES를 사용하여 임시 테이블을 만드는 데 선호되는 방법입니다.
테이블을 만들고 삽입하는 대신 일부 값을 선택하려는 경우 다음과 같은 작업을 수행 할 수 있습니다.
WITH vals (k,v) AS (VALUES (0,-9999), (1, 100))
SELECT * FROM vals;
실제로 비슷한 방식으로 임시 테이블을 만들려면 다음을 사용하십시오.
WITH vals (k,v) AS (VALUES (0,-9999), (1, 100))
SELECT * INTO temporary table temp_table FROM vals;
편집 : 로는에, 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;
또한 a_horse_with_no_name의 의견과 OP의 원래 질문에서 값 목록 내의 올바른 데이터 유형으로의 캐스트가 포함되며 CTE (WITH) 문을 사용합니다.
또한 Evan Carrol의 답변에서 지적했듯이 CTE 쿼리는 최적화 펜스입니다 . 즉, CTE는 항상 구체화됩니다. CTE를 사용하는 데는 여러 가지 이유가 있지만주의해서 사용하지 않으면 성능이 크게 저하 될 수 있습니다. 그러나 최적화 펜스가 실제로 성능을 향상시킬 수있는 경우가 많기 때문에 맹목적으로 피할 수는 없습니다.
답변
create table as
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);
CTE를 사용하도록 이것을 다시 작성할 수도 있습니다.
create temp table lookup
as
with t (key, value) as (
values
(0::int,-99999::numeric),
(1::int,100::numeric)
)
select * from t;
답변
문제는 데이터 유형입니다. 그것들을 제거하면 진술이 작동합니다.
CREATE TEMP TABLE lookup
(key, val) AS
VALUES
(0, -99999),
(1, 100) ;
첫 번째 행의 값을 캐스트하여 유형을 정의 할 수 있습니다.
CREATE TEMP TABLE lookup
(key, val) AS
VALUES
(0::bigint, -99999::int),
(1, 100) ;
답변
쿼리에 몇 가지 값을 사용하는 것만으로도 테이블을 만들거나 CTE를 사용할 필요가 없습니다. 당신은 그들을 인라인 할 수 있습니다 :
SELECT *
FROM (VALUES(0::INT, -99999::NUMERIC), (1, 100)) AS lookup(key, val)
그런 다음 CROSS JOIN
(다른 관계는 물론 일반 테이블, 뷰 등 이 될 수있는) 직교 제품을 얻을 수 있습니다. 예 :
SELECT *
FROM (VALUES(0::int, -99999::numeric), (1, 100)) AS lookup(key, val)
,(VALUES('Red'), ('White'), ('Blue')) AS colors(color);
결과는 다음과 같습니다.
key |val |color |
----|-------|------|
0 |-99999 |Red |
1 |100 |Red |
0 |-99999 |White |
1 |100 |White |
0 |-99999 |Blue |
1 |100 |Blue |
또는 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;
결과는 다음과 같습니다.
key |val |color |lookup_key |
----|-------|------|-----------|
1 |100 |Red |1 |
0 |-99999 |White |0 |
1 |100 |Blue |1 |
답변
먼저 항상 표준화 사용 CREATE TABLE AS
, SELECT INTO
10 년 이상 사용되지 않는 구문되었습니다 다른 답변에 제안. CTE와 함께 사용할 수 있습니다CREATE TABLE AS
여기에 많은 답변이 CTE 사용을 제안하고 있지만 바람직하지 않습니다. 실제로 다소 느려질 수 있습니다. 그냥 테이블로 마무리하십시오.
DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup(key, value) AS
VALUES
(0::int,-99999::numeric),
(1,100);
select 문을 작성해야하는 경우에도 그렇게 할 수 있습니다 (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);
PostgreSQL의 CTE는 materialization을 강제합니다. 최적화 펜스입니다. 따라서 비용을 이해하고 성능 향상을 제공 할 수있는 경우를 제외하고는 어느 곳에서나 사용하는 것이 일반적으로 좋지 않습니다. 예를 들어 여기에서 느려진 것을 볼 수 있습니다.
\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
답변
WITH u AS (
SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS account (id,name)
)
SELECT id, name, length(name) from u;