需要计算 SQL 中日期之间连续 30 天内的操作数

Need to count the number of operations within a rolling 30-day period between dates in SQL

我有一个 table 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_idover_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

您可以将 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 是一个 db<>fiddle.

类似的方法给了我你想要的结果(我将字段 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