2016-08-30 58 views
2

我試圖使用Postgres的tablefunc擴展的CROSSTAB函數對某些數據執行一個數據透視操作。數據首先需要進行一些轉換,我在公用表表達式中執行了一些轉換。無法在Postgres交叉表查詢中使用公用表表達式

但是,看起來CROSSTAB看不到這些表達式的結果。

例如,來自一個臨時表這個查詢的採購數據正常工作:

CREATE TEMPORARY TABLE 
    temporary_table 
    (name, category, category_value) 
ON COMMIT DROP 
AS (
    VALUES 
    ('A', 'foo', 1   ), 
    ('A', 'bar', 2   ), 
    ('B', 'foo', 3   ), 
    ('B', 'bar', 4   ) 
); 

SELECT * FROM 
    CROSSTAB(
    'SELECT * FROM temporary_table', 
    $$ 
     VALUES 
     ('foo'), 
     ('bar') 
    $$ 
) AS (
    name TEXT, 
    foo INT, 
    bar INT 
); 

,正如預期的,產生以下輸出:

name | foo  | bar 
text | integer | integer 
---- | ------- | ------- 
A |  1 |  2 
B |  3 |  4 

但相同的查詢,這時間使用公用表表達式不運行:

WITH 
    common_table 
    (name, category, category_value) 
AS (
    VALUES 
    ('A', 'foo', 1   ), 
    ('A', 'bar', 2   ), 
    ('B', 'foo', 3   ), 
    ('B', 'bar', 4   ) 
) 
SELECT * FROM 
    CROSSTAB(
    'SELECT * FROM common_table', 
    $$ 
     VALUES 
     ('foo'), 
     ('bar') 
    $$ 
) AS (
    name TEXT, 
    foo INT, 
    bar INT 
) 

,併產生以下錯誤:

ERROR: relation "common_table" does not exist 
LINE 1: SELECT * FROM common_table 
        ^
QUERY: SELECT * FROM common_table 

********** Error ********** 

ERROR: relation "common_table" does not exist 
SQL state: 42P01 

我把它這意味着文本查詢(SELECT * FROM common_table)運行在某種不同的環境呢?


注:tablefunc擴展名必須是啓用CROSSTAB可用:

CREATE EXTENSION IF NOT EXISTS tablefunc; 

回答

1

所有你需要做的就是將你的CTE裏面的字符串作爲第一個參數crosstab(text, text)函數只是就像你對select語句所做的一樣。它將被正確解析和執行。這是因爲您提供了完整的SQL語句,可以在第一個參數中生成源代碼集。

你需要加倍您的引號裏面的字符串或者使用美元符$$就像你用第二個參數,我做如下:

SELECT * FROM 
    CROSSTAB(
    $$ 
    WITH common_table(name, category, category_value) AS (
     VALUES 
     ('A', 'foo', 1   ), 
     ('A', 'bar', 2   ), 
     ('B', 'foo', 3   ), 
     ('B', 'bar', 4   ) 
    ) 
    SELECT * FROM common_table $$, 
    $$ 
     VALUES 
     ('foo'), 
     ('bar') 
    $$ 
) AS (
    name TEXT, 
    foo INT, 
    bar INT 
); 

結果

name | foo | bar 
------+-----+----- 
A | 1 | 2 
B | 3 | 4