SQL比较每个分区项目的动态时间

时间:2018-07-16 00:30:46

标签: sql sql-server sql-server-2012

我想查找所有不良交易发生前0-5分钟内发生的交易,并使用cardkey进行分区。例如,我需要将所有cardley = 999的trans_time与bad_trans_time(5/27/18 6:42 AM)进行比较

样本数据

trans_key   trans_time       cardkey    bad_trans_key   bad_trans_time
1         4/15/18 2:00 AM      999        NULL           NULL
2         4/15/18 2:01 AM      999        NULL           NULL
3         5/27/18 6:38 AM      999        NULL           NULL
4         5/27/18 6:39 AM      999        NULL           NULL
5         5/27/18 6:40 AM      999        NULL           NULL
6         5/27/18 6:41 AM      999        NULL           NULL
7         5/27/18 6:42 AM      999         7       5/27/18 6:42 AM
8         5/27/18 6:43 AM      999        NULL           NULL
9         3/24/18 2:36 AM      333        NULL           NULL
10        3/24/18 2:37 AM      333        NULL           NULL
11        3/24/18 2:38 AM      333        NULL           NULL
12        3/24/18 2:39 AM      333         12      3/24/18 6:39 AM
13        3/24/18 2:40 AM      333        NULL           NULL

预期产量

trans_key   trans_time       cardkey    bad_trans_key   bad_trans_time
3         5/27/18 6:38 AM      999        NULL           NULL
4         5/27/18 6:39 AM      999        NULL           NULL
5         5/27/18 6:40 AM      999        NULL           NULL
6         5/27/18 6:41 AM      999        NULL           NULL
8         5/27/18 6:43 AM      999        NULL           NULL
9         3/24/18 2:36 AM      333        NULL           NULL
10        3/24/18 2:37 AM      333        NULL           NULL
11        3/24/18 2:38 AM      333        NULL           NULL

2 个答案:

答案 0 :(得分:1)

一种方法使用exists

select t.*
from t
where exists (select 1
              from t t2
              where t2.cardkey = t.cardkey and
                    t2.bad_trans_time is not null and
                    t.trans_time >= dateadd(minute, -5, t2.bad_trans_time) and
                    t.trans_time <= t2.bad_trans_time
             );

答案 1 :(得分:0)

另一种使用窗口函数的方法:

WITH 
  BadTransTime AS (
    SELECT trans_key, trans_time, cardkey, bad_trans_key, bad_trans_time
      , MAX(bad_trans_time) OVER (PARTITION BY cardkey) AS cardkey_bad_trans_time
    FROM t
  )
SELECT trans_key, trans_time, cardkey, bad_trans_key, bad_trans_time
FROM BadTransTime 
WHERE DATEADD(minute, 5, bad_trans_time) >= cardkey_bad_trans_time
  AND bad_trans_time < cardkey_bad_trans_time