2012-07-31 49 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