【问题标题】:SQL query with new column for each unique attribute in table表中每个唯一属性的新列的 SQL 查询
【发布时间】:2021-08-10 21:13:49
【问题描述】:

一些背景知识:我的 Postgres 数据库中有一个表

daily(date DATE,ticker VARCHAR(10),adjusted_close FLOAT),例如

date ticker adjusted_close
2021-02-01 ABC 23.2
2021-02-01 CCC 222.2
2021-02-02 ABC 24.2
2021-02-02 CCC 220.4

我想进行一个查询,无论存在多少唯一代码,都返回一个像这样的表:

date ABC CCC
2021-02-01 23.2 222.2
2021-02-02 24.2 220.4

我已经阅读了 Postgres 中的 PIVOT() 函数,但我无法找到让它工作的方法。有没有人遇到过同样的问题并想出了解决办法?

【问题讨论】:

    标签: sql postgresql pivot


    【解决方案1】:

    在 Postgres PIVOT 中通常使用过滤聚合来完成:

    select d.date, 
           max(d.adjusted_close) filter (where d.ticker = 'ABC') as abc,
           max(d.adjusted_close) filter (where d.ticker = 'CCC') as ccc
    from daily d
    group by d.date;
    

    在你问之前:你不能让这个“动态”。在解析查询时和实际执行之前,必须知道查询的编号、名称和数据类型。您不能在查询开始后才确定列的查询。


    另一种方法可能是将单个日期的所有内容聚合为 JSON 值:

    select d.date, 
           jsonb_object_agg(d.ticker, d.adjusted_close) as ticker_info
    from daily d
    group by d.date;
    

    【讨论】:

    • 感谢您的回复! json 方法效果很好,但并没有真正做到我想要的。我想在函数中执行这个查询,所以在执行查询之前可能知道数字、名称和数据类型
    【解决方案2】:

    这在 mssql 中对我有用。希望它也适用于 Postgres。

    DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ticker) 
    FROM daily c
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')
    
    
    set @query = 'SELECT [date], ' + @cols + ' from 
            (
               SELECT  [date]
               ,[ticker]
               ,[adjusted_close]
               FROM daily
            ) x
            pivot 
            (
                min([adjusted_close])
                for [ticker] in (' + @cols + ')
            ) p '
    
    execute(@query)
    

    【讨论】:

    • 或许可以翻译成Postgresql,试一试。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 2016-09-28
    • 2021-10-04
    相关资源
    最近更新 更多