我可以使用一系列 10 分钟记录作为累积值来计算某个站点自上午 9 点以来的降雨量,但是嵌套 SQL 似乎很冗长,我希望使其更加简洁,以便将来可维护。我可以使用 CTE,这可能会使其更干净一些,但想知道是否有一种方法可以通过 SUM & PARTITION BY 在一次调用中获得此结果,而不使用我当前的 CASE 方法?
以下 postgres 查询使用 10 分钟值计算自上午 9 点以来的降雨量。首先,我添加一个字段来确定这一天是上午 9 点之前还是之后 - 在这种情况下,我想将上午 9 点和零分钟作为前几天“上午 9 点以来的降雨量”值的一部分,但 9:01 之后的任何内容都应该是重点此时运行总计重置。我知道我在此示例中使用 10 分钟记录,但我确实希望精确到分钟,因为会有其他站点以分钟为单位进行报告,但此示例站点仅以 10 分钟为单位进行报告。
SELECT
site_name,
date_time_utc AT TIME ZONE 'Australia/Hobart' AS date_time_local,
precip_10min,
precip_since_9am,
day_9am_val,
SUM(precip_10min) OVER
(PARTITION BY site_name, day_9am_val ORDER BY date_time_utc) AS precip_since_9am_cal
FROM
(
SELECT *,
CASE
WHEN DATE_PART('hour', date_time_utc AT TIME ZONE 'Australia/Hobart') > 9 THEN (date_time_utc AT TIME ZONE 'Australia/Hobart')::date
WHEN DATE_PART('hour', date_time_utc AT TIME ZONE 'Australia/Hobart') < 9 THEN ((date_time_utc AT TIME ZONE 'Australia/Hobart')::date - INTERVAL '1 day')::date
WHEN DATE_PART('minutes', date_time_utc AT TIME ZONE 'Australia/Hobart') > 0 THEN (date_time_utc AT TIME ZONE 'Australia/Hobart')::date
ELSE ((date_time_utc AT TIME ZONE 'Australia/Hobart')::date - INTERVAL '1 day')::date
END AS day_9am_val
FROM
temp_export
) tbl
ORDER BY
site_name, date_time_utc DESC
预期值作为 precip_since_9am 提供,计算值(应匹配)为 precip_since_9am_cal。 day_9am_val 不是必需的,它只是说明我如何处理划分上午 9 点截止时间的问题。我已在 SQL fiddle here 中放置了一小部分数据,但还在下面显示了一些示例行:
站点名称 | 本地日期时间 | 沉淀_10分钟 | precip_since_9am | day_9am_val | precip_since_9am_cal |
---|---|---|---|---|---|
网站 | 2024-01-18 17:00:00 | 0.2 | 10.8 | 2024-01-18 | 10.8 |
网站 | 2024-01-18 16:50:00 | 0.4 | 10.6 | 2024-01-18 | 10.6 |
网站 | 2024-01-18 16:40:00 | 0.2 | 10.2 | 2024-01-18 | 10.2 |
网站 | 2024-01-18 16:30:00 | 0.2 | 10 | 2024-01-18 | 10.0 |
网站 | 2024-01-18 16:20:00 | 0.4 | 9.8 | 2024-01-18 | 9.8 |
我最终根据 NickW 的建议重写以删除子选择,并将案例直接包含在分区字段中:
SELECT
site_name,
date_time_utc AT TIME ZONE 'Australia/Hobart' AS date_time_local,
precip_10min,
precip_since_9am,
SUM(precip_10min) OVER (PARTITION BY site_name, (CASE
WHEN (date_time_utc AT TIME ZONE 'Australia/Hobart')::time > '9:00'
THEN (date_time_utc AT TIME ZONE 'Australia/Hobart')::date
ELSE ((date_time_utc AT TIME ZONE 'Australia/Hobart')::date - INTERVAL '1 day')::date
END) ORDER BY date_time_utc) AS precip_since_9am_calc
FROM
temp_export
ORDER BY
site_name, date_time_utc DESC