需要在 SQL 中计算日期之间滚动的 30 天期间内的操作数
Posted
技术标签:
【中文标题】需要在 SQL 中计算日期之间滚动的 30 天期间内的操作数【英文标题】:Need to count the number of operations within a rolling 30-day period between dates in SQL 【发布时间】:2021-09-09 12:37:33 【问题描述】:我有一个表 Mytable,其中 id - 成员的 id 和 dp_id - 部门的 id:
date id dp_id
2020-11-14 01:22:10.260 300000 002
2020-11-14 01:41:13.260 352575 001
2020-11-14 16:39:31.910 352575 001
2020-11-14 23:39:52.510 352575 001
2020-11-14 00:00:00.260 300000 002
2020-11-15 00:01:20.710 352575 001
2020-11-15 01:00:43.600 352575 001
2020-11-15 13:41:19.410 352575 002
如果id
- dp_id
(352575
- 001
) 对的第一次交易后 30 天内的操作数超过 5,则应标记为 over_lim
。
例如,如果id
-dp_id
的第一个操作是在01: 41: 13.260
,因此,在接下来的 30 天内,我需要计算那里有多少操作,如果有超过5.
即2020-11-15 01: 00: 43.600 352575 001
操作将是 id
-dp_id
对的第一个条目的第 5 个操作,因此我们将其标记为 over_lim
。以此类推 - 我们需要获取该期间的第一笔交易,然后查看接下来 30 天的交易量。
预期输出,其中tr_count
- 每对交易的计数id
-dp_id
,over_lim
- 我们的标记,这是一个超限交易(>=5):
date id dp_id tr_count over_lim
2020-11-14 01:22:10.260 300000 002 1 False
2020-11-14 01:41:13.260 352575 001 1 False
2020-11-14 16:39:31.910 352575 001 2 False
2020-11-14 23:39:52.510 352575 001 3 False
2020-11-14 00:00:00.260 300000 002 2 False
2020-11-15 00:01:20.710 352575 001 4 False
2020-11-15 01:00:43.600 352575 001 5 True
2020-11-15 13:41:19.410 352575 002 1 False
【问题讨论】:
为什么最后一行没有被标记?它是大于 5 的第 6 个。 @GordonLinoff 因为它是一个新的 id-dp_id 对 352575 - 002,所以它是它的第一个条目 【参考方案1】:您可以将count(*)
与range
一起使用:
select t.*,
count(*) over (partition by id
order by date
range between interval '30' day preceding and interval '0' day preceding
) as tr_count,
(case when count(*) over (partition by id
order by date
range between interval '30' day preceding and interval '0' day preceding
) >= 5
then 'true' else 'false'
end) as over_lim
from t;
如果您只希望第五个是'true'
,则将>= 5
更改为= 5
。
Here 是一个 dbfiddle。
【讨论】:
我认为使用间隔'-30'前一天和当前行之间的范围会更好 @GordonLinoff 我没有得到 tr_count 列中每个条目的正确累积总数,我如何更改此脚本以达到上述预期输出中的结果 @Kurasao 。 . .我修正了错别字。我认为它现在会起作用。不过,我不确定你想要>= 5
还是= 5
。
@GordonLinoff 看起来它与 row_number() 一起使用效果更好,但是当我在 tr_count 应用它而不是 count(*) 时,我得到了缺少右括号的错误。同样在您的虚拟数据库示例中,您得到了正确答案,但在我的海量表格中,它只是将每对 id 的总计数 - tr_count 中的 dp_id 用于 ex 6,而不是 1、2、3 等
@Kurasao 。 . . row_number()
不接受 range
窗框规范。【参考方案2】:
类似的方法给了我你想要的结果(我将字段 date
更改为 date_oper
)
SQL> with t as
2 (
3 select to_date('2020-11-14 01:22:10','yyyy-mm-dd hh24:mi:ss') date_oper, 300000 id, '002' dp_id from dual union all
4 select to_date('2020-11-14 01:41:13','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '001' dp_id from dual union all
5 select to_date('2020-11-14 16:39:31','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '001' dp_id from dual union all
6 select to_date('2020-11-14 23:39:52','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '001' dp_id from dual union all
7 select to_date('2020-11-14 00:00:00','yyyy-mm-dd hh24:mi:ss') date_oper, 300000 id, '002' dp_id from dual union all
8 select to_date('2020-11-15 00:01:20','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '001' dp_id from dual union all
9 select to_date('2020-11-15 01:00:43','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '001' dp_id from dual union all
10 select to_date('2020-11-15 13:41:19','yyyy-mm-dd hh24:mi:ss') date_oper, 352575 id, '002' dp_id from dual
11 )
12 select t.*,
13 count(*) over (partition by id, dp_id order by date_oper range between interval '30' day preceding and current row) as tr_count,
14 (case when count(*) over (partition by id, dp_id order by date_oper range between interval '30' day preceding and current row) >= 5
15 then 'true' else 'false'
16 end) as over_lim
17* from t order by date_oper
SQL> /
DATE_OPER ID DP_ TR_COUNT OVER_
------------------- ---------- --- ---------- -----
2020-11-14 00:00:00 300000 002 1 false
2020-11-14 01:22:10 300000 002 2 false
2020-11-14 01:41:13 352575 001 1 false
2020-11-14 16:39:31 352575 001 2 false
2020-11-14 23:39:52 352575 001 3 false
2020-11-15 00:01:20 352575 001 4 false
2020-11-15 01:00:43 352575 001 5 true
2020-11-15 13:41:19 352575 002 1 false
8 rows selected.
你可以在这里查看
db<>fiddle
【讨论】:
看起来它与 row_number() 一起使用效果更好,但是当我在 tr_count 应用它而不是 count(*) 时,我得到了缺少右括号的错误。同样在您的虚拟数据库示例中,您得到了正确答案,但在我的海量表格中,它只是将每对 id 的总计数 - tr_count 中的 dp_id 用于 ex 6,而不是 1、2、3 等 @Kurasao,row_number()
不承认范围,所以它不能工作。关于结果,也许您应该更好地解释所需的输出,据我所见,我的查询得到了您按预期放置的输出。您可以编辑问题并添加更多行以更好地理解您期望的逻辑吗?
刚刚解决了我的问题,应该使用时间戳日期列 11/11/2020 6:13:45,000000 ,而不是日期 11/11/2020,它会导致总数。非常感谢!以上是关于需要在 SQL 中计算日期之间滚动的 30 天期间内的操作数的主要内容,如果未能解决你的问题,请参考以下文章