在 PostgreSQL 中计算移动天气统计数据
Calculate moving weather stats in PostgreSQL
我正在尝试在我的 PostgreSQL table 天气数据中计算自上次下雨以来的天数以及该事件中每一天的降雨量。我一直在尝试使用 window 函数来实现这一点,但是范围必须是无界的限制让我对如何进行有点困惑。
这是我目前的查询:
SELECT
station_num,
ob_date,
rain,
max(rain) OVER (PARTITION BY station_num ORDER BY ob_date ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as prev_rain_mm,
'' as days_since_rain --haven't attempted this calculation yet
FROM
obs_daily_ground_moisture
结果如下:
但我正在尝试实现更像这样的东西:
我觉得关于 window 函数范围和过滤器以及嵌套查询的所有部分都在那里,但我不确定如何将它们整合在一起。此外,上述数据只是实际数据集的一个子集,整个数据集刚刚超过 50 万行。
这里的关键是对从第一次出现雨值>0 值到下一次出现雨值>0 值的观测值进行分组。此后,您可以使用 window 函数来计算所需的列。
select
x.station_num,
x.ob_date,
max(rain) over(partition by station_num,col) prev_rain,
case when rain > 0 then 0
else row_number() over(partition by station_num, col order by ob_date)-1 end days_since_rain
from (select t.*,
sum(case when rain > 0 then 1 else 0 end) over(partition by station_num order by ob_date) col
from t) x
试试这个。
DECLARE @Rain AS FLOAT
UPDATE A
SET
@Rain = CASE WHEN A.Rain = 0 THEN @Rain ELSE A.Rain END,
A.Rain = CASE WHEN @Rain IS NULL OR A.Rain <> 0 THEN A.Rain ELSE @Rain END
FROM obs_daily_ground_moisture A
SELECT ob_date, Rain,
max(rain) OVER (PARTITION BY station_num ORDER BY ob_date ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as prev_rain_mm,
ROW_NUMBER() OVER(PARTITION BY Rain ORDER BY ob_date) - 1 as days_since_rain
FROM obs_daily_ground_moisture ORDER BY ob_date
我正在尝试在我的 PostgreSQL table 天气数据中计算自上次下雨以来的天数以及该事件中每一天的降雨量。我一直在尝试使用 window 函数来实现这一点,但是范围必须是无界的限制让我对如何进行有点困惑。 这是我目前的查询:
SELECT
station_num,
ob_date,
rain,
max(rain) OVER (PARTITION BY station_num ORDER BY ob_date ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as prev_rain_mm,
'' as days_since_rain --haven't attempted this calculation yet
FROM
obs_daily_ground_moisture
结果如下:
但我正在尝试实现更像这样的东西:
我觉得关于 window 函数范围和过滤器以及嵌套查询的所有部分都在那里,但我不确定如何将它们整合在一起。此外,上述数据只是实际数据集的一个子集,整个数据集刚刚超过 50 万行。
这里的关键是对从第一次出现雨值>0 值到下一次出现雨值>0 值的观测值进行分组。此后,您可以使用 window 函数来计算所需的列。
select
x.station_num,
x.ob_date,
max(rain) over(partition by station_num,col) prev_rain,
case when rain > 0 then 0
else row_number() over(partition by station_num, col order by ob_date)-1 end days_since_rain
from (select t.*,
sum(case when rain > 0 then 1 else 0 end) over(partition by station_num order by ob_date) col
from t) x
试试这个。
DECLARE @Rain AS FLOAT
UPDATE A
SET
@Rain = CASE WHEN A.Rain = 0 THEN @Rain ELSE A.Rain END,
A.Rain = CASE WHEN @Rain IS NULL OR A.Rain <> 0 THEN A.Rain ELSE @Rain END
FROM obs_daily_ground_moisture A
SELECT ob_date, Rain,
max(rain) OVER (PARTITION BY station_num ORDER BY ob_date ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as prev_rain_mm,
ROW_NUMBER() OVER(PARTITION BY Rain ORDER BY ob_date) - 1 as days_since_rain
FROM obs_daily_ground_moisture ORDER BY ob_date