我有下表,其中包含时间序列数据。一个“数据集”的所有数据点都具有相同的时间戳和值“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 查询中解决这个问题吗?
提前致谢!
尼可
您可以选择不同的名称,并通过在 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;
由于您可能不知道每个时间戳/常量对的值的数量,因此将值列表存储到数组中而不是存储在单独的列中更相关。那么就这么简单-
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;
演示
不相关但使用保留字作为名称并不是一个好主意。