在Sql Server中使用游标统计拒绝尝试次数

在Sql Server中使用游标统计拒绝尝试次数,sql,sql-server,tsql,Sql,Sql Server,Tsql,您好,我被这个问题困住了,我在SQL SERVER中通过游标找到了一个解决方案,但我的行数约为400K,输出需要几个小时,有人能更快地完成吗?也许通过交叉申请或其他方式。多谢各位 问题: 只需统计交易状态已拒绝,如果TransactionStatus已批准,计数器将重置回零 事务日志 AccountNumber CardNumber TransactionStatus EntryDate 10845522-XYZ 5471XXXXXXXX1111 Approved 10

您好,我被这个问题困住了,我在SQL SERVER中通过游标找到了一个解决方案,但我的行数约为400K,输出需要几个小时,有人能更快地完成吗?也许通过交叉申请或其他方式。多谢各位

问题: 只需统计交易状态已拒绝,如果TransactionStatus已批准,计数器将重置回零

事务日志

AccountNumber CardNumber TransactionStatus EntryDate 10845522-XYZ 5471XXXXXXXX1111 Approved 10/09/2013 10845522-XYZ 5471XXXXXXXX1111 Declined 10/09/2014 10845522-XYZ 5471XXXXXXXX1111 Declined 10/09/2015 10845522-XYZ 5471XXXXXXXX9999 Approved 10/09/2016 10845522-ABC 5471XXXXXXXX6666 Declined 10/09/2012 10845522-ABC 5471XXXXXXXX6666 Declined 10/09/2019 10845522-DEF 5471XXXXXXXX7777 Declined 10/09/2016 10845522-DEF 5471XXXXXXXX7777 Approved 10/09/2019 所需产量

AccountNumber CardNumber DeclineCounter ModifiedDate 10845522-XYZ 5471XXXXXXXX1111 2 10/09/2015 10845522-XYZ 5471XXXXXXXX9999 0 10/09/2016 10845522-ABC 5471XXXXXXXX6666 2 10/09/2019 10845522-DEF 5471XXXXXXXX7777 0 10/09/2019 我的代码/方法使用游标和Merge语句,工作正常,但由于游标的原因需要几个小时才能完成

-- Main Transaction Table
Select row_number() Over(Order by EntryDate) RowNumber
,Account, CARD_NUMBER, TransactionStatus, EntryDate
into dbo.TransactionLog_Temp
from dbo.TransactionLog


-- Cursor
DECLARE @RowNumber AS INT
DECLARE C CURSOR FOR
        Select Rownumber from dbo.TransactionLog_Temp order by Rownumber ASC

OPEN C

FETCH NEXT FROM C INTO @RowNumber;

    WHILE @@FETCH_STATUS = 0
    BEGIN

    -- Decide Update or Insert
    MERGE INTO dbo.Declined_Counter_Table AS T
    USING (Select Account,TransactionStatus,CARD_NUMBER,EntryDate 
    from TransactionLog_Temp where Rownumber=@RowNumber) S ON T.Account=S.Account AND T.CARD_NUMBER=S.CARD_NUMBER
        WHEN MATCHED AND T.ModifiedDate<>S.EntryDate
            THEN UPDATE SET T.[Counter] = CASE WHEN S.TransactionStatus ='Declined' THEN ISNULL(T.[Counter],0) + 1
                                                WHEN S.TransactionStatus ='Approved' THEN 0 END
                    ,T.ModifiedDate = S.EntryDate                             
        WHEN NOT MATCHED BY TARGET AND S.TransactionStatus ='Declined'
            THEN INSERT VALUES (S.Account, S.CARD_NUMBER,1, S.EntryDate);

    -- remove from main table, to resume the query anyother time since its taking too long
        Delete from dbo.TransactionLog_Temp where Rownumber=@RowNumber

    print @RowNumber
        FETCH NEXT FROM C INTO @RowNumber;
    END;

CLOSE C;
DEALLOCATE C; 

您似乎需要一个聚合:

Select Account, CARD_NUMBER,
       sum(case when TransactionStatus = 'Declined' then 1 else 0 end) as num_all_declines,
       sum(case when TransactionStatus = 'Declined' and
                     (EntryDate > last_approved_ed or last_approved_ed is null
                     )
                then 1 else 0 
           end) as num_recent_declines,           
       max(EntryDate)
from (select tl.*,
             max(case when TransactionStatus = 'Approved' then EntryDate end) over (partition by Account, CARD_NUMBER) as last_approved_ed
      from dbo.TransactionLog tl) query
group by Account, CARD_NUMBER;

这应该比尝试使用光标快得多。

您似乎想要一个聚合:

Select Account, CARD_NUMBER,
       sum(case when TransactionStatus = 'Declined' then 1 else 0 end) as num_all_declines,
       sum(case when TransactionStatus = 'Declined' and
                     (EntryDate > last_approved_ed or last_approved_ed is null
                     )
                then 1 else 0 
           end) as num_recent_declines,           
       max(EntryDate)
from (select tl.*,
             max(case when TransactionStatus = 'Approved' then EntryDate end) over (partition by Account, CARD_NUMBER) as last_approved_ed
      from dbo.TransactionLog tl) query
group by Account, CARD_NUMBER;

这应该比尝试使用光标要快得多。

通过EntryDate>Last\u Approved\u Ed计算在我的脑海中,但不确定如何输入查询。我一直在考虑交叉应用和游标。您的查询在2秒内执行。谢谢,伙计。通过EntryDate>Last_Approved_Ed进行计算在我的脑海中,但不确定如何输入查询。我一直在考虑交叉应用和游标。您的查询在2秒内执行。谢谢你,伙计。