【问题标题】:Postgres - partial pivot with crosstabPostgres - 带有交叉表的部分枢轴
【发布时间】:2021-06-25 18:12:17
【问题描述】:

我很挣扎,知道搜​​索答案的术语可能是我的问题,因为我无法想象这是一个极端情况。

dbfiddle available

我在 Postgres 9.4 中有一张桌子:

CREATE TABLE test (
    id serial PRIMARY KEY, cust_id INTEGER,
    category VARCHAR, key INTEGER, value INTEGER
); 
INSERT INTO test (cust_id, category, key, value)
VALUES
    (1, 'alpha', 0,300),(1, 'bravo', 0,150),(1, 'alpha', 1,300),
    (1, 'bravo', 1,200),(1, 'alpha', 2,300),(1, 'bravo', 2,250),
    (2, 'alpha', 0,301),(2, 'bravo', 0,151),(2, 'alpha', 1,301),
    (2, 'bravo', 1,201),(2, 'alpha', 2,301),(2, 'bravo', 2,251),
    (3, 'alpha', 0,302),(3, 'bravo', 0,152),(3, 'alpha', 1,302),
    (3, 'bravo', 1,202),(3, 'alpha', 2,302),(3, 'bravo', 2,252);


 id | cust_id | category | key | value 
----+---------+----------+-----+-------
  1 |       1 | alpha    |   0 |   300
  2 |       1 | bravo    |   0 |   150
  3 |       1 | alpha    |   1 |   300
  4 |       1 | bravo    |   1 |   200
  5 |       1 | alpha    |   2 |   300
  6 |       1 | bravo    |   2 |   250
  7 |       2 | alpha    |   0 |   301
  8 |       2 | bravo    |   0 |   151
  9 |       2 | alpha    |   1 |   301
 10 |       2 | bravo    |   1 |   201
 11 |       2 | alpha    |   2 |   301
 12 |       2 | bravo    |   2 |   251
 13 |       3 | alpha    |   0 |   302
 14 |       3 | bravo    |   0 |   152
 15 |       3 | alpha    |   1 |   302
 16 |       3 | bravo    |   1 |   202
 17 |       3 | alpha    |   2 |   302
 18 |       3 | bravo    |   2 |   252
(18 rows)

我想查询如下所示的结果:

 cust_id | category |  0  |  1  |  2  
---------+----------+-----+-----+-----
       1 | alpha    | 300 | 300 | 300 
       1 | bravo    | 150 | 200 | 250 
       2 | alpha    | 301 | 301 | 301
       2 | bravo    | 151 | 201 | 251
       3 | alpha    | 302 | 302 | 302
       3 | bravo    | 152 | 202 | 252
(6 rows)

我试过了:

SELECT
    *
FROM
    crosstab(
        'SELECT cust_id,category,key,value FROM test ORDER BY cust_id,category,key',
        $$values ('0'::INT),
        ('1'::INT),
        ('2'::INT) $$
    ) AS ct (
        "cust_id" INT, "category" TEXT, "0" INT,
        "1" INT, "2" INT
    );

这让我很着迷(缺少 bravo 类别行并在第 1、2、3 列中使用 bravo 值):

 cust_id | category |  0  |  1  |  2  
---------+----------+-----+-------
       1 | alpha    | 150 | 200 | 250 
       2 | alpha    | 151 | 201 | 251
       3 | alpha    | 152 | 202 | 252
(2 rows)

我通过删除 cust_id 字段并限制为单个 id 来更接近以下内容:

SELECT
    *
FROM
    crosstab(
        'SELECT category,key,value FROM test WHERE cust_id = 1 ORDER BY category,key',
        $$values ('0'::INT),
        ('1'::INT),
        ('2'::INT) $$
    ) AS ct (
        "category" TEXT, "0" INT,
        "1" INT, "2" INT
    );

但这仅给出单个cust_id 的结果,但我需要为所有客户提供此结果:

 category |  0  |  1  |  2  
----------+-----+-------
 alpha    | 300 | 300 | 300 
 bravo    | 150 | 200 | 250 
(2 rows)

https://dbfiddle.uk/?rdbms=postgres_9.5&fiddle=2c75cf9a1b18bb980ddd72953235d54e

【问题讨论】:

    标签: postgresql pivot-table crosstab


    【解决方案1】:

    这是一种方法:

    select cust_id , category  
        , max(case when key = 0 then value end) "0" 
        , max(case when key = 1 then value end) "1"
        , max(case when key = 2 then value end) "2"
    from test
    group by cust_id , category
    order by cust_id , category 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多