使用Postgres将多个行值转换为列名

时间:2018-07-21 07:39:00

标签: sql postgresql pivot

我有一张这样的桌子:

computeValue

我想变成

   public class Test {

    public static void main(String[] args) {
        double[] decMax = {-2.8, -8.8, 2.3, 7.9, 4.1, -1.4, 11.3, 10.4,
            8.9, 8.1, 5.8, 5.9, 7.8, 4.9, 5.7, -0.9, -0.4, 7.3, 8.3, 6.5, 9.2,
            3.5, 3, 1.1, 6.5, 5.1, -1.2, -5.1, 2, 5.2, 2.1};

        double maxx = decMax[0];

        for (int i = 0; i < decMax.length; i++) {
            if (maxx < decMax[i]) {
                maxx = decMax[i];
            }
        }
        System.out.println(maxx);

    }
}

我尝试使用case语句,但无法达到结果。

2 个答案:

答案 0 :(得分:1)

您可以尝试将CASE WHENMAX函数一起使用来制作数据透视表。

TestDLL

CREATE TABLE T(
    State VARCHAR(5),
    city VARCHAR(5),
    year  INT,
    series VARCHAR(5),
    values INT
);

INSERT INTO T VALUES ('s1','c1',1980,'se_1',1);
INSERT INTO T VALUES ('s1','c1',1981,'se_1',2);
INSERT INTO T VALUES ('s1','c1',1982,'se_1',3);
INSERT INTO T VALUES ('s1','c1',1980,'se_2',4);
INSERT INTO T VALUES ('s1','c1',1981,'se_2',5);
INSERT INTO T VALUES ('s1','c1',1982,'se_2',6);
INSERT INTO T VALUES ('s1','c2',1980,'se_1',1);
INSERT INTO T VALUES ('s1','c2',1981,'se_1',2);
INSERT INTO T VALUES ('s1','c2',1982,'se_1',3);
INSERT INTO T VALUES ('s1','c2',1980,'se_2',4);
INSERT INTO T VALUES ('s1','c2',1981,'se_2',5);
INSERT INTO T VALUES ('s1','c2',1982,'se_2',6);
INSERT INTO T VALUES ('s2','c1',1980,'se_1',1);
INSERT INTO T VALUES ('s2','c1',1981,'se_1',2);
INSERT INTO T VALUES ('s2','c1',1982,'se_1',3);
INSERT INTO T VALUES ('s2','c1',1980,'se_2',4);
INSERT INTO T VALUES ('s2','c1',1981,'se_2',5);
INSERT INTO T VALUES ('s2','c1',1982,'se_2',6);
INSERT INTO T VALUES ('s2','c2',1980,'se_1',1);
INSERT INTO T VALUES ('s2','c2',1981,'se_1',2);
INSERT INTO T VALUES ('s2','c2',1982,'se_1',3);
INSERT INTO T VALUES ('s2','c2',1980,'se_2',4);
INSERT INTO T VALUES ('s2','c2',1981,'se_2',5);
INSERT INTO T VALUES ('s2','c2',1982,'se_2',6);

查询

SELECT State,
       city,
       MAX(CASE WHEN series ='se_1' AND year = 1980 THEN "values" END) as se_1_1980,
       MAX(CASE WHEN series ='se_1' AND year = 1981 THEN "values" END) as se_1_1981,
       MAX(CASE WHEN series ='se_1' AND year = 1982 THEN "values" END) as se_1_1982,
       MAX(CASE WHEN series ='se_2' AND year = 1980 THEN "values" END) as se_2_1980,
       MAX(CASE WHEN series ='se_2' AND year = 1981 THEN "values" END) as se_2_1981,
       MAX(CASE WHEN series ='se_2' AND year = 1982 THEN "values" END) as se_2_1982 
FROM  T
GROUP BY 
       State,
       city

sqlfiddle

注意

避免使用关键字作为表的列名,例如valuesyear ... 您可以使用其他名称代替

答案 1 :(得分:0)

之前

stackoverflow.com: Dynamic alternative to pivot with CASE and GROUP BY

如果可以“ json”更好地选择。

with T0 as (
SELECT
  State,
  city,
  series || '_' || trim(both ' ' from to_char(year, '9999')) series_year,
  max(values) values_max
FROM T
group by 
  1,2,3
order by 
  1,2,3
)
select 
  State,
  city,
  jsonb_object_agg(series_year, values_max) AS data_json
from T0
group by
  1,2
state | city | data_json                                                                                       
:---- | :--- | :-----------------------------------------------------------------------------------------------
s2    | c1   | {"se_1_1980": 1, "se_1_1981": 2, "se_1_1982": 3, "se_2_1980": 4, "se_2_1981": 5, "se_2_1982": 6}
s2    | c2   | {"se_1_1980": 1, "se_1_1981": 2, "se_1_1982": 3, "se_2_1980": 4, "se_2_1981": 5, "se_2_1982": 6}
s1    | c2   | {"se_1_1980": 1, "se_1_1981": 2, "se_1_1982": 3, "se_2_1980": 4, "se_2_1981": 5, "se_2_1982": 6}
s1    | c1   | {"se_1_1980": 1, "se_1_1981": 2, "se_1_1982": 3, "se_2_1980": 4, "se_2_1981": 5, "se_2_1982": 6}

db <>提琴here


用户交叉表

信息

-- info
SELECT
  state  || '_' || city state_city,
  series || '_' || trim(both ' ' from to_char(year, '9999')) series_year,
  max(values) values_max
FROM T
group by 
  1,2
order by 
  1,2
state_city | series_year | values_max
:--------- | :---------- | ---------:
s1_c1      | se_1_1980   |          1
s1_c1      | se_1_1981   |          2
s1_c1      | se_1_1982   |          3
s1_c1      | se_2_1980   |          4
s1_c1      | se_2_1981   |          5
s1_c1      | se_2_1982   |          6
s1_c2      | se_1_1980   |          1
s1_c2      | se_1_1981   |          2
s1_c2      | se_1_1982   |          3
s1_c2      | se_2_1980   |          4
s1_c2      | se_2_1981   |          5
s1_c2      | se_2_1982   |          6
s2_c1      | se_1_1980   |          1
s2_c1      | se_1_1981   |          2
s2_c1      | se_1_1982   |          3
s2_c1      | se_2_1980   |          4
s2_c1      | se_2_1981   |          5
s2_c1      | se_2_1982   |          6
s2_c2      | se_1_1980   |          1
s2_c2      | se_1_1981   |          2
s2_c2      | se_1_1982   |          3
s2_c2      | se_2_1980   |          4
s2_c2      | se_2_1981   |          5
s2_c2      | se_2_1982   |          6

信息

-- info
SELECT distinct  series || '_' || trim(both ' ' from to_char(year, '9999')) series_year FROM T order by 1
| series_year |
| :---------- |
| se_1_1980   |
| se_1_1981   |
| se_1_1982   |
| se_2_1980   |
| se_2_1981   |
| se_2_1982   |
with T2 as(
select 
  *
from crosstab(
  '
SELECT
  state  || ''_'' || city state_city,
  series || ''_'' || trim(both '' '' from to_char(year, ''9999'')) series_year,
  max(values) values_max
FROM T group by 1,2 order by 1,2',
  'SELECT distinct series || ''_'' || trim(both '' '' from to_char(year, ''9999'')) series_year FROM T order by 1'
  )
as newtable (
  state_city text,
  se_1_1980 text,
  se_1_1981 text,
  se_1_1982 text,
  se_2_1980 text,
  se_2_1981 text,
  se_2_1982 text
  )
)
select 
  split_part(state_city,'_',1) state,
  split_part(state_city,'_',2) city,
  se_1_1980,
  se_1_1981,
  se_1_1982,
  se_2_1980,
  se_2_1981,
  se_2_1982
from T2
state | city | se_1_1980 | se_1_1981 | se_1_1982 | se_2_1980 | se_2_1981 | se_2_1982
:---- | :--- | :-------- | :-------- | :-------- | :-------- | :-------- | :--------
s1    | c1   | 1         | 2         | 3         | 4         | 5         | 6        
s1    | c2   | 1         | 2         | 3         | 4         | 5         | 6        
s2    | c1   | 1         | 2         | 3         | 4         | 5         | 6        
s2    | c2   | 1         | 2         | 3         | 4         | 5         | 6        

db <>提琴here