【发布时间】:2014-03-31 00:17:19
【问题描述】:
我的数据集包含来自不同行业的不同公司的每日(实际上是工作日)时间序列,我使用 PostgreSQL。我的数据集中有一个指标变量,取值 1、-1,大多数情况下为 0。为了更好地理解问题,我将指标变量不等于零的日子称为指标事件。
因此对于前三个工作日内同一行业的另一个指标事件之前的所有指标事件,指标变量应更新为零。
我们可以想到以下示例数据集:
day company industry indicator
2012-01-12 A financial 1
2012-01-12 B consumer 0
2012-01-13 A financial 1
2012-01-13 B consumer -1
2012-01-16 A financial 0
2012-01-16 B consumer 0
2012-01-17 A financial 0
2012-01-17 B consumer 0
2012-01-17 C consumer 0
2012-01-18 A financial 0
2012-01-18 B consumer 0
2012-01-18 C consumer 1
因此,应更新为零的指标值在 2012-01-13 是公司 A 的条目,在 2012-01-18 是公司 C 的条目,因为它们之前是同一个中的另一个指标事件3 个工作日内的行业。
我尝试通过以下方式完成它:
UPDATE test SET indicator = 0
WHERE (day, industry) IN (
SELECT day, industry
FROM (
SELECT industry, day,
COUNT(CASE WHEN indicator <> 0 THEN 1 END)
OVER (PARTITION BY industry ORDER BY day
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) As cnt
FROM test
) alias
WHERE cnt >= 2)
我的想法是按行业划分当天和前 3 天的指标事件数。如果计数大于 1,则将指标值更新为零。
弱点是,到目前为止,它计入了前三行(按行业划分),而不是前三个工作日。因此,在示例数据中,它无法在 2012 年 1 月 18 日更新公司 C,因为它计算了最后三个行业 = 消费者的行,而不是计算过去三个工作日行业 = 消费者的所有行。
我尝试了不同的方法,例如在代码的倒数第三行添加另一个子查询或在倒数第三行后添加WHERE EXISTS - 子句,以确保代码计数超过前三个日期。但没有任何效果。我真的不知道该怎么做(我只是学习使用 PostgreSQL)。
您有任何解决方法的想法吗?
或者也许我的想法完全错误,您知道如何解决我的问题的另一种方法?
【问题讨论】:
-
如果同一行业每三个工作日就有一个指标会怎样?您是否重置除第一个指标之外的所有指标?你不应该有一个静态网格吗?比如,“只从周一到周三选择第一个事件,从周四到周五选择第一个事件”。
-
是的,在这种情况下,我会重置除第一个以外的所有指标。因此,您的解决方案运行良好,非常感谢。 @ErwinBrandstetter
标签: sql postgresql sql-update time-series window-functions