有没有更简单的方法来编写 generate_series 生成多列的代码?
Is there a simpler way to write generate_series code for generating multiple columns?
generate_series
函数是 Postgres 中非常酷的功能之一,但我觉得很困惑。如果您想要 单个 系列数字、递增的时间戳等,这非常简单。但当您想要用多列填充测试数据行时,(对我而言)就不是那么明显了。我今天需要这样的东西,所以我想我会再试一次。下面的代码 确实 生成了我想要的内容,一个计数器和一个匹配小时的时间戳。我最终对数字序列使用了 CTE,然后在时间戳计算中重复使用。
有没有更简单的方法?
而且,是的,用另一种语言甚至 Excel 等生成这样的模拟数据会很容易。但我很想弄清楚如何在 Postgres 中做事。这个样本是完全合成的,但很多时候部分数据来自 Postgres 中的现有数据。
感谢建议等
CREATE TABLE IF NOT EXISTS api.sample_series (
id INTEGER NOT NULL DEFAULT 0,
stamp timestamptz NOT NULL DEFAULT NULL,
CONSTRAINT sample_series_id_pkey
PRIMARY KEY (id)
);
-- Generate a series of numbers for each hour of the year. It's okay if I'm off by one here, I'm only running a test. So 1 through 8760.
WITH
counter as (
select * from generate_series(1,8760,1) as hour_number),
-- Now use that series to generate two columns, the original counter/hour_number and a calculated timestamp to match
values as (
select hour_number as id,
'2019-01-01 00:00'::timestamp + interval '1' HOUR * hour_number as stamp
from counter)
-- You've now got 8,760 numbers and timestamps, push them into the table.
INSERT INTO api.sample_series (id,stamp)
SELECT id,stamp from values```
这两个 CTE 是不需要的,在我看来对提高可读性没有任何作用。
所以更简单的方法是:
INSERT INTO api.sample_series (id,stamp)
select
hour_number as id,
'2019-01-01 00:00'::timestamp + interval '1 HOUR' * hour_number as stamp
from generate_series(1,8760,1) as hour_number;
不幸的是,"stamp" 的表达式文本很长,但我认为将其隐藏在 CTE 后面并没有多大意义。
generate_series
函数是 Postgres 中非常酷的功能之一,但我觉得很困惑。如果您想要 单个 系列数字、递增的时间戳等,这非常简单。但当您想要用多列填充测试数据行时,(对我而言)就不是那么明显了。我今天需要这样的东西,所以我想我会再试一次。下面的代码 确实 生成了我想要的内容,一个计数器和一个匹配小时的时间戳。我最终对数字序列使用了 CTE,然后在时间戳计算中重复使用。
有没有更简单的方法?
而且,是的,用另一种语言甚至 Excel 等生成这样的模拟数据会很容易。但我很想弄清楚如何在 Postgres 中做事。这个样本是完全合成的,但很多时候部分数据来自 Postgres 中的现有数据。
感谢建议等
CREATE TABLE IF NOT EXISTS api.sample_series (
id INTEGER NOT NULL DEFAULT 0,
stamp timestamptz NOT NULL DEFAULT NULL,
CONSTRAINT sample_series_id_pkey
PRIMARY KEY (id)
);
-- Generate a series of numbers for each hour of the year. It's okay if I'm off by one here, I'm only running a test. So 1 through 8760.
WITH
counter as (
select * from generate_series(1,8760,1) as hour_number),
-- Now use that series to generate two columns, the original counter/hour_number and a calculated timestamp to match
values as (
select hour_number as id,
'2019-01-01 00:00'::timestamp + interval '1' HOUR * hour_number as stamp
from counter)
-- You've now got 8,760 numbers and timestamps, push them into the table.
INSERT INTO api.sample_series (id,stamp)
SELECT id,stamp from values```
这两个 CTE 是不需要的,在我看来对提高可读性没有任何作用。
所以更简单的方法是:
INSERT INTO api.sample_series (id,stamp)
select
hour_number as id,
'2019-01-01 00:00'::timestamp + interval '1 HOUR' * hour_number as stamp
from generate_series(1,8760,1) as hour_number;
不幸的是,"stamp" 的表达式文本很长,但我认为将其隐藏在 CTE 后面并没有多大意义。