窗口函数通过当前行过滤

窗口函数通过当前行过滤,第1张

窗口函数通过当前行过滤

我可以使用框架和滤镜吗?

可以的 。但是两者都有限制:

  • FILTER
    子句中的表达式只能看到其获取值的相应行。无法引用窗口函数为其计算值的行。因此 除非我们进行 巨大而昂贵的 交叉 联接, 否则我看不到根据 行制定过滤器的方法-同一行用于许多不同的计算。或者,我们又回到了
    LATERAL
    那个子查询 引用父行。

这些限制使您的特定查询难以实施。现在应该是 正确的

SELECt *FROM  (   SELECt record_id, security_id, date, price        , CASE WHEN do_calc THEN     max(earnings) OVER w1     END AS peak_earnings        , CASE WHEN do_calc THEN     min(earnings) OVER w1     END AS minimum_earnings        , CASE WHEN do_calc THEN price / NULLIF(max(earnings) OVER w1, 0) END AS price_to_peak_earnings        , CASE WHEN do_calc THEN price / NULLIF(min(earnings) OVER w1, 0) END AS price_to_minimum_earnings   FROM  (      SELECt *, (date - 365) >= min_date AND s.record_id IS NOT NULL AS do_calc      FROM  (         SELECt security_id, min_date   , generate_series(min_date, max_date, interval '1 day')::date AS date         FROM  ( SELECt security_id, min(date) AS min_date, max(date) AS max_date FROM   security_data GROUP  BY 1 ) minmax         ) d      LEFT   JOIN  security_data s USING (security_id, date)      ) sub1   WINDOW w1 AS (PARTITION BY security_id ORDER BY date ROWS BETWEEN 365 PRECEDING AND 1 PRECEDING)   ) sub2WHERe  record_id IS NOT NULL ORDER  BY 1, 2;

SQL提琴。

笔记
  • 问题中没有什么可以说每个

    security_id
    人在同一天都有行。计算
    security_id
    子查询中每个的最小/最大日期
    minmax
    将为我们提供最短的时间范围。

  • 计算的时间范围恰好是该行当前日期之前的365天,并且 包括当前行(

    ROWS BETWEEN 365 PRECEDING AND 1 PRECEDING
    )。通常, 当前行从要与当前行进行比较的聚合中 排除 会更有用。
    我将计算条件调整到了相同的时间范围,以避免出现极端情况:
    (date - 365) >= min_date

  • 在小提琴中,在1月1日的每一行中添加了1行,您可以看到leap年与固定天数365天形成对比的效果。leap年(2001,2005,…)之后,窗框为空。

  • 我正在使用所有子查询,通常比CTE快一点。

  • 可以肯定的是,我们需要

    ORDER BY
    在框架定义中包括。

  • 我将“ 1年”期间
    w1
    用作窗口 名称 。您可以添加
    w2
    ,等等,每个可以有任意天数。毕竟,如果需要,您可以适应leap年。甚至可能根据当前日期生成整个查询…


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5431819.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存