Timescale/PostgreSQL - 透视时间序列数据

问题描述 投票:0回答:2

我有下表,其中包含时间序列数据。一个“数据集”的所有数据点都具有相同的时间戳和值“const”。以下示例显示了其中两个“数据集”。

+-----------+----------+----------+-------------+
| timestamp |  const   |   name   |    value    |
+-----------+----------+----------+-------------+
|    t0     |    A     |   name1  |   value0_1  |
+-----------+----------+----------+-------------+
|    t0     |    A     |   name2  |   value0_2  |
+-----------+----------+----------+-------------+
|    t0     |    A     |   name3  |   value0_3  |
+-----------+----------+----------+-------------+
|    t0     |    A     |   name4  |   value0_4  |
+-----------+----------+----------+-------------+
|    t1     |    B     |   name1  |   value1_1  |
+-----------+----------+----------+-------------+
|    t1     |    B     |   name2  |   value1_2  |
+-----------+----------+----------+-------------+
|    t1     |    B     |   name3  |   value1_3  |
+-----------+----------+----------+-------------+
|    t1     |    B     |   name4  |   value1_4  |
+-----------+----------+----------+-------------+

现在,我想将此数据集从行转换为列。这意味着每一行都有一个完整的数据集。

+-----------+----------+----------+----------+----------+----------+
| timestamp |  const   |   name1  |   name2  |   name3  |   name4  |
+-----------+----------+----------+----------+----------+----------+
|    t0     |    A     | value0_1 | value0_2 | value0_3 | value0_4 |
+-----------+----------+----------+----------+----------+----------+
|    t1     |    B     | value1_1 | value1_2 | value1_3 | value1_3 |
+-----------+----------+----------+----------+----------+----------+

有什么建议可以在优雅的 Timescale/PostgreSQL 查询中解决这个问题吗?

提前致谢!

尼可

postgresql pivot
2个回答
0
投票

您可以选择不同的名称,并通过在 string_agg 的帮助下连接查询子句和部分来生成文本,一方面将名称粘合到动态字段列表中,另一方面将左联接粘合在一起。下面的查询就是这样一个例子,但它没有经过测试,所以它可能包含我的拼写错误或错误。

select concat(
    'select timestamp, const, ',
    string_agg(concat('table_', name, '.' name), ','),
    ' ',
    'from yourtable yt ',
    string_agg(concat(
        'left join table_',
        name,
        ' ',
        'on ',
        'yt.timestamp = table_', name, '.timestamp and ',
        'yt.const = table_', name, '.const and ',
        'table_', name, '.name = \'', name, '\''
    ), ' ')
)
from (select distinct name from yourtable) t;

0
投票

由于您可能不知道每个时间戳/常量对的值的数量,因此将值列表存储到数组中而不是存储在单独的列中更相关。那么就这么简单-

select "timestamp", const, 
       array_agg(distinct "value") as names
from the_table
group by "timestamp", const;

演示
如果这与您的情况更相关,您可以使用

jsonb_agg
而不是
array_agg
将列表作为 JSON 数组。

如果您需要结果中“name”列的内容,那么结果可能是对象的 JSON 数组:

select "timestamp", const, 
       jsonb_agg(json_build_object(name, "value")) as names
from the_table
group by "timestamp", const;

演示
不相关但使用保留字作为名称并不是一个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.