sql - SQL Oracle 中的滚动 90 天日期窗口
问题描述
SELECT *
FROM (SELECT date'2021-05-06' AS tran_dt FROM dual UNION
SELECT date'2021-05-24' FROM dual UNION
SELECT date'2021-06-25' FROM dual UNION
SELECT date'2021-07-02' FROM dual UNION
SELECT date'2021-07-27' FROM dual UNION
SELECT date'2021-08-16' FROM dual UNION
SELECT date'2021-08-23' FROM dual UNION
SELECT date'2021-10-01' FROM dual UNION
SELECT date'2021-12-31' FROM dual)
你好
我正在使用 SQL Oracle 中的日期字段。
我正在尝试创建滚动窗口,该窗口返回第一行并在自上次返回行以来的日期> 90 时返回另一行。
在下面的示例中,我想计算并返回警报字段 = 是的位置。
如果有人有任何想法,将不胜感激。
谢谢
席7
TRAN_DT Alert Days Since Last Alert
06/05/2021 Yes 0
24/05/2021 No 18
25/06/2021 No 50
02/07/2021 No 57
27/07/2021 No 82
16/08/2021 Yes 102
23/08/2021 No 7
01/10/2021 No 46
31/12/2021 Yes 137
解决方案
From Oracle 12, this is the sort of query that MATCH_RECOGNIZE
is intended for:
SELECT tran_dt,
alert,
tran_dt
- LAG(CASE alert WHEN 'Yes' THEN tran_dt END, 1, tran_dt)
IGNORE NULLS OVER (ORDER BY tran_dt)
AS days
FROM table_name
MATCH_RECOGNIZE (
ORDER BY tran_dt
MEASURES
CLASSIFIER() AS alert
ALL ROWS PER MATCH
PATTERN ( "Yes" "No"* )
DEFINE
"No" AS tran_dt <= "Yes".tran_dt + INTERVAL '90' DAY
)
Before Oracle 12, you can use a recursive query:
WITH dates (tran_dt, rn) AS (
SELECT tran_dt,
ROW_NUMBER() OVER (ORDER BY tran_dt) AS rn
FROM table_name
),
rolling_dates (tran_dt, alert, rn, days, last_alert) AS (
SELECT tran_dt, 'Yes', rn, 0, tran_dt
FROM dates
WHERE rn = 1
UNION ALL
SELECT d.tran_dt,
CASE
WHEN d.tran_dt <= r.last_alert + INTERVAL '90' DAY
THEN 'No'
ELSE 'Yes'
END,
d.rn,
d.tran_dt - r.last_alert,
CASE
WHEN d.tran_dt <= r.last_alert + INTERVAL '90' DAY
THEN r.last_alert
ELSE d.tran_dt
END
FROM rolling_dates r
INNER JOIN dates d
ON (r.rn + 1 = d.rn)
)
SELECT tran_dt,
alert,
days
FROM rolling_dates;
Both of which outputs:
TRAN_DT ALERT DAYS 2021-05-06 00:00:00 Yes 0 2021-05-24 00:00:00 No 18 2021-06-25 00:00:00 No 50 2021-07-02 00:00:00 No 57 2021-07-27 00:00:00 No 82 2021-08-16 00:00:00 Yes 102 2021-08-23 00:00:00 No 7 2021-10-01 00:00:00 No 46 2021-12-31 00:00:00 Yes 137
db<>fiddle here
推荐阅读
- html - CSS 网格:使用 ::after 下划线效果来适应网格项目
- python - 符号的第一次和最后一次出现(没有正则表达式的python)
- python - 使用 pybind11 调用 Python 函数时避免复制输入数据
- java - 不使用 Eclipse 快捷方式以编程方式调用方法的层次结构
- java - 在 JavaFX 项目中添加模块时,出现错误“未设置位置”
- assembly - 编译器生成的标签是什么意思?
- reactjs - 如何在反应中获取绑定函数中的名称属性?
- reactjs - Eslint 不应该强制 props 字段在 React 中是只读的吗?
- javascript - 对 React 的 useMemo 的 Typescript 调用要求所有依赖项具有相同的类型
- php - 在我的环境文件中使用外部 Laravel API 搜索变量