2012-07-31 76 views
2

我有一個prefs表,這裏的相關列:PostgreSQL的交叉表/透視問題

mydb=> SELECT pref_id, pref_name, pref_value FROM prefs; 
pref_id | pref_name | pref_value 
---------+--------------+---------------- 
     1 | PagerNumber | 2125551234 
     2 | PagerCarrier | @att.com 
     3 | PagerCarrier | @something.com 

我想產生這樣的事:

section | pager_number | pager_carrier 
---------+----------------+--------------- 
     1 | 2125551234  | 
     2 |    | @att.com 
     3 |    | @something.com 

所以我用交叉表,下面這例如在計算器:PostgreSQL Crosstab Query

SELECT row_name AS section, 
     category_1::text AS pager_number, 
     category_2::text AS pager_carrier 
FROM crosstab('select pref_id::bigint, pref_name::text, pref_value::text 
    FROM prefs') 
AS ct (row_name bigint, category_1 text, category_2 text); 

所有數值都進入pager_number,並pager_carrier保留爲空:

section | pager_number | pager_carrier 
---------+----------------+--------------- 
     1 | 2125551234  | 
     2 | @att.com  | 
     3 | @something.com | 

任何人都可以看到這是怎麼回事?

回答

3

測試用例(首選的方式提供樣本數據):

CREATE TEMP TABLE prefs (pref_id int, pref_name text, pref_value text); 

INSERT INTO prefs VALUES 
(1, 'PagerNumber' , '2125551234') 
,(2, 'PagerCarrier', '@att.com') 
,(3, 'PagerCarrier', '@something.com'); 

查詢:

SELECT * 
FROM crosstab(
     'SELECT pref_id, pref_name, pref_value 
     FROM prefs 
     ORDER BY 1, 2', 

     $$VALUES ('PagerNumber'::text), ('PagerCarrier')$$ 
     ) 
AS x (section text, pager_number bigint, pager_carrier text); 

正好返回在你的問題中所描繪的結果。如果PagerNumber可能不是有效的bigint號碼,請改爲使用text

你在你的問題中提到的答案已經過時,從來沒有正確的開始。我添加了一個proper answer with explanation and links over there.

0

相反的:

SELECT row_name AS section, category_1::text AS pager_number, category_2::text 
AS pager_carrier 
FROM crosstab('select pref_id::bigint, pref_name::text, pref_value::text 
    FROM prefs') 
AS ct (row_name bigint, category_1 text, category_2 text); 

嘗試:

SELECT * 
FROM crosstab('select pref_id::bigint, pref_name::text, pref_value::text 
FROM prefs ORDER BY 1,2') 
AS prefs (row_name bigint, carrier_1 text, carrier_2 text); 

如果您有:

pref_id | pref_name | pref_value 
    ---------+--------------+---------------- 
    1 | PagerNumber | 2125551234 
    2 | PagerCarrier | @att.com 
    3 | PagerCarrier | @something.com 
    2 | PageNumber | 2332323232 
    3 | PagerCarrier | @somethingelse.com 

你會得到:

row_name | carrier_1 | carrier_2 
    -----+--------------+---------------- 
    1 | 2125551234  | 
    2 | @att.com  | 2332323232 
    3 | @something.com | @somethingelse.com 

Postgress Crosstab Reference

+0

謝謝,但你的解決方案沒有什麼不同,我得到了同樣的結果。你所指的語法錯誤在哪裏? – nnyby 2012-08-01 00:17:08

+0

對不起,我無法訪問Postgress來試用它。嘗試像我在示例中那樣添加順序。 – Edmon 2012-08-01 00:40:54

+0

我看到發生了什麼 - 你得到一個交叉表,但它看起來並不像你期望的那樣。它是crosstabbing/pivoting pref id和值。嘗試插入更多的名稱和值的組合。它應該開始顯示一個關鍵點。我認爲你的標籤也讓你感到困惑。 – Edmon 2012-08-01 00:50:44