我一直在尝试根据task_dts的值过滤code
具有一定值的行。实际上我只想要每个id的行数其中task_dts
时间戳落在当前code
的code_dts
时间戳和后面的code_dts
时间戳之间。code
.
例如;对于code
等于'z'的行,我只想要task_dts
在code_dts
的值'z'和值'y'范围内的行。对于code
等于'y'的行,我只想要task_dts
在code_dts
范围内的行,用于值'y'和值'x'等
我的表如下所示:
<表类>rowid id 代码 code_dts 任务 task_dts tbody><<tr>1 z 2022-02-01 10:17:08.403000 1 2022-02-01 10:21:27.000000 2z 2022-02-01 10:17:08.403000 2 2022-02-01 10:21:31.000000 3 z 2022-02-01 10:17:08.403000 3 2022-02-01 12:41:43.000000 4y 2022-02-01 11:12:13.270000 1 2022-02-01 10:21:27.000000 5y 2022-02-01 11:12:13.270000 3 2022-02-01 12:41:43.000000 6y 2022-02-01 11:12:13.270000 8 2022-02-21 14:57:53.000000 7x 2022-02-21 12:28:50.647000 6 2022-02-21 14:57:53.000000 8x 2022-02-21 12:28:50.647000 7 2022-02-21 14:57:54.000000 9道明> h 2022-04-05 13:44:16.030000 1 2022-04-05 14:03:56.570000 10道明> h 2022-04-05 13:44:16.030000 2 2022-04-05 14:03:56.570000 11道明> 我 2022-04-06 13:44:16.030000 1 2022-04-05 14:03:56.570000 12道明> j 2022-04-07 13:44:16.030000 3 2022-04-05 14:03:56.570000 表类>
可以使用表表达式预先计算时间戳范围。这样,过滤就容易了。
例如:
select t.*
from t
join (
select code, dt, lead(dt) over(order by dt) as next_dt
from (select code, min(code_dts) as dt from t group by code) x
) y on t.code = y.code
where t.task_dts between y.dt and y.next_dt or y.next_dt is null
看了The Impaler的回答后,我终于明白了你的要求:-)
这是基于窗口函数的相同逻辑:
with cte as
(
select t.*
-- next code_dts, i.e. at least one row will return
-- the code_dts of the following code
,lead(code_dts,1,task_dts) over (order by code_dts) as next_dts
from tab as t
)
select *
from cte
qualify task_dts between code_dts
-- assign the next code's dts to all rows within the same code
and max(next_dts) over (partition by code)
;
很难说哪一个会做得更好…