postgresql数据透视

o0lyfsai  于 2021-08-13  发布在  Java
关注(0)|答案(4)|浏览(278)

我是sql查询领域的新手,希望能在数据透视方面得到帮助。我有一张类似的table:

我想变成这样:

我敢打赌这是一个非常简单的过程,但仍然会感谢任何帮助。

vwoqyblh

vwoqyblh1#

sql小提琴
postgresql 9.6架构设置:

CREATE TABLE MyTable (Description varchar(255), Label varchar(255),Val varchar(255));
INSERT INTO MyTable (Description,Label,Val) VALUES ('Name1','Location','Europe')
,('Name1','Depth','1200'),('Name1','Date','24.2.2011'),('Name2','Location','Australia')
,('Name2','Depth','3233'),('Name2','Date','1.1.1999'),('Name3','Location','Africa')
,('Name3','Depth','1323'),('Name3','Date','15.2.2018')

查询1:

with CTE AS (select *,
(CASE WHEN Label='Location' THEN Val  END) AS Location,
(CASE WHEN Label = 'Depth' THEN Val END) AS Depth,
(CASE WHEN Label='Date' THEN Val END) AS Dates,
ROW_NUMBER() OVER (PARTITION BY Label,Val Order By Description) as rn
from MyTable
group by Label,Description,Val              )

select c.Description
,max(c.Location) AS Location
,max(c.Depth) AS Depth
,max(c.Dates) AS Dates
from cte c
where rn=1
group by c.Description 
order by c.Description

结果:

| description |  location | depth |     dates |
|-------------|-----------|-------|-----------|
|       Name1 |    Europe |  1200 | 24.2.2011 |
|       Name2 | Australia |  3233 |  1.1.1999 |
|       Name3 |    Africa |  1323 | 15.2.2018 |
s4n0splo

s4n0splo2#

一个技巧是聚合到一个json(b)字段中,并将其解包。与任何eav一样,您仍然需要处理正确的数据类型。

CREATE table eav
        ( description text
        , label text
        , value text
        );

INSERT INTO eav(description, label, value) VALUES
 ( 'name1' , 'location' , 'Europe') , ( 'name1' , 'depth' , '1200') , ( 'name1' , 'date' , '24.2.2011')
 , ( 'name2' , 'location' , 'Australia') , ( 'name2' , 'depth' , '3233') , ( 'name2' , 'date' , '1.1.1999')
 , ( 'name3' , 'location' , 'Africa') , ( 'name3' , 'depth' , '1323') , ( 'name3' , 'date' , '12.5.2018')
        ;

SELECT xx.description
        , xx.ja->>'location' AS location
        , (xx.ja->>'depth')::integer AS depth
        , to_date(xx.ja->>'date', 'dd.m.yyyy') AS zdate
FROM    (       -- Aggregate EAV into json
        SELECT e.description
        , json_object_agg( e.label, e.value) AS ja
        FROM eav e
        GROUP BY 1
        ) xx
        ;

结果:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 9
 description | location  | depth |   zdate    
-------------+-----------+-------+------------
 name3       | Africa    |  1323 | 2018-05-12
 name2       | Australia |  3233 | 1999-01-01
 name1       | Europe    |  1200 | 2011-02-24
(3 rows)
shstlldc

shstlldc3#

您可以使用tablefunc&crosstab()实现所需的结果,而不需要太复杂。为此,您需要创建下面的扩展 CREATE EXTENSION IF NOT EXISTS tablefunc; 一个select语句就可以了,

SELECT *
FROM crosstab('SELECT Description, Label, Val
    FROM   bar
    ORDER  BY 1'
    ) AS ct("Description" text, "Location" text, "Depth" text, "Date" text);

演示

fdbelqdn

fdbelqdn4#

您可以不使用suq query进行条件聚合:

select description, 
       max(value) filter (where label = 'location') as location,
       max(value) filter (where label = 'depth') as depth,
       max(value) filter (where label = 'zdate') as zdate
from table t
group by description;

相关问题