我有一个名为 metric 的时间刻度数据库,其中存储了许多不同的参数,有些是字符串值,有些是整数值。基本上,我有一个名为“carbon”的参数,它是一个整数值,我有一个名为“stationName”的字符串值。此查询的目标是仅当 stationName 等于“ST2”时显示给定时间段内的碳值。任何有关如何完成此操作的帮助将不胜感激,因为这是我第一次处理时间序列查询。
下面我添加了到目前为止我尝试过的示例查询和数据库的架构。
数据库架构
timestamp - 时间戳值
参数 - 参数名称
data_text - 当参数是文本类型时使用
data_float - 当参数为数字时使用
WITH
-- a and b are for reading data
a AS ( SELECT
timestamp AS t,
data_float AS carbon
FROM
metric
WHERE
parameter = 'db.C'
AND timestamp BETWEEN $START_TIME::timestamp AND $END_TIME
),
b AS (
SELECT
timestamp AS t,
data_text AS station
FROM metric
WHERE parameter = 'db.StationName'
AND timestamp BETWEEN $START_TIME::timestamp AND $END_TIME
),
c AS (
SELECT t, carbon, NULL AS station FROM a
UNION ALL
SELECT t, NULL AS carbon, station FROM b
),
d AS (
SELECT *,
COUNT(carbon) OVER (ORDER BY t) AS grp
FROM c
),
e AS (
SELECT t,
carbon AS carbon_val,
station AS station_val
FROM d
)
SELECT
t AS timestamp,
carbon_val,
station_val,
'db.C_for_ST2' As columns
FROM e
WHERE
station_val = "ST2"
AND t BETWEEN $START_TIME AND $END_TIME```
我会开始将它们分解为视图,以使问题更容易解决:
create view station_events as
SELECT
timestamp AS t,
data_text AS station
FROM metric
WHERE parameter = 'db.StationName'
碳事件也一样:
create view carbon_events as SELECT
timestamp AS t,
data_float AS carbon
FROM
metric;
现在,用 CTE 来过滤电台:
WITH the_station AS
(select * from station_events where station = 'ST2' and BETWEEN $START_TIME::timestamp AND $END_TIME)
SELECT station, (select count(*) FROM carbon_events WHERE carbon_events.time BETWEEN the_station.time and $END_TIME)) as carbon_count from the_station;
我不确定查询是否正确,我受到这个主题的启发来回答最后一部分:PostgreSQL:加入另一个表的计数
您还可以考虑使用更高级的组件,例如状态跟踪。