【问题标题】:PostgreSQL crosstab/pivot problemsPostgreSQL 交叉表/数据透视问题
【发布时间】:2012-07-31 23:59:26
【问题描述】:

我有一个prefs 表,以下是相关列:

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

所以我使用了交叉表,按照 stackoverflow 上的这个例子: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_numberpager_carrier 留空:

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

谁能看到发生了什么?

【问题讨论】:

    标签: sql postgresql plpgsql postgresql-9.1 crosstab


    【解决方案1】:

    测试用例(提供样本数据的首选方式):

    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.

    【讨论】:

      【解决方案2】:

      代替:

      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

      【讨论】:

      • 谢谢,但您的解决方案没有区别,我得到了相同的结果。您指的语法错误在哪里?
      • 很抱歉,我无法访问 Postgress 来尝试它。尝试像我在示例中所做的那样添加 order by。
      • 我知道发生了什么 - 你得到一个交叉表,但它看起来不像你期望的那样。它是交叉表/透视pref id和值。尝试插入更多名称和值的组合。它应该开始显示一个支点。我认为您的标签也让您感到困惑。
      猜你喜欢
      • 1970-01-01
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多