识别 SQL 中的账户间转账

Posted

技术标签:

【中文标题】识别 SQL 中的账户间转账【英文标题】:Identify Inter-Account Transfers in SQL 【发布时间】:2016-03-14 05:37:41 【问题描述】:

我在 SQL 表中有一堆银行交易。

示例:http://sqlfiddle.com/#!6/6b2c8/1/0

我需要确定在这 2 个关联帐户之间进行的交易。帐户表(未显示)将这 2 个帐户链接到一个来源(用户)。

例如: 我有一个日常账户和一个储蓄账户。有时,我可能会将钱从我的日常账户转入我的储蓄账户(反之亦然)。

交易描述通常是相似的(转账到xxx/从xxx转账),通常是在同一天,而且显然是相同的美元金额。

编辑:我现在有以下查询(已简化),适用于某些场景

基本上,我创建了 2 个临时表,其中包含满足特定条件的所有提款和存款。然后,我根据一些要求(相同的交易金额、不同的帐户编号等)将它们连接在一起。然后使用 ROW_NUMBER 函数,我排序了哪些更有可能是跨账户交易。

我现在有一个问题,例如:

100 美元从账户 A 转入账户 B

$100 从账户 B 转入账户 C

我的查询会匹配账户A和C之间的转账,那么账户B只有一笔交易,不会被匹配。所以本质上,我没有收到 2 行(2 次存款,2 次取款),而是收到 1 行(1 次存款,1 次取款),用于从 A 到 B 的转移:(

INSERT  INTO #Deposits
        SELECT  t.*
        FROM    dbo.Customer c
                INNER JOIN dbo.Source src ON src.AppID = app.AppID
                INNER JOIN dbo.Account acc ON acc.SourceID = src.SourceID
                INNER JOIN dbo.Tran t ON t.AccountID = acc.AccountID
        WHERE   c.CustomerID = 123
                AND t.Template = 'DEPOSIT'

INSERT  INTO #Withdrawals
        SELECT  t.*
        FROM    dbo.Customer c
                INNER JOIN dbo.Source src ON src.AppID = app.AppID
                INNER JOIN dbo.Account acc ON acc.SourceID = src.SourceID
                INNER JOIN dbo.Tran t ON t.AccountID = acc.AccountID
        WHERE   c.CustomerID = 123
                AND t.Template = 'WITHDRAWAL'

;WITH    cte
          AS ( SELECT   [...] , 
                        ROW_NUMBER() OVER ( PARTITION BY d.TranID ORDER BY SUM( CASE WHEN d.TranDate = d.TranDate THEN 2 ELSE 1 END), w.TranID  ) AS DepRN,
                        ROW_NUMBER() OVER ( PARTITION BY w.TranID ORDER BY SUM( CASE WHEN d.TranDate = d.TranDate THEN 2 ELSE 1 END ), d.TranID ) AS WdlRN
               FROM     #Withdrawal w
                        INNER JOIN d ON w.TranAmount = d.TranAmount -- Same transaction amount
                                               AND w.AccountID <> d.AccountID -- Different accounts, same customer
                                               AND w.TranDate BETWEEN d.TranDate AND DATEADD(DAY, 3, d.TranDate) -- Same day, or within 3 days
               GROUP BY [...]
             )
    SELECT  *
    FROM    cte
    WHERE cte.DepRN = cte.WdlRN

【问题讨论】:

【参考方案1】:

也许这是一个开始?我认为我们没有足够的信息来说明这是否可靠或会导致大量“误报”。

select t1.TransactionID, t2.TransactionID
from dbo.Transactions as t1 inner join dbo.Transactions as t2
    on      t2.AccountID = t2.AccountID
        and t2.TransactionDate = t1.TransactionDate
        and t2.TransactionAmount = t1.TransactionAmount
        and t2.TransactionID - t1.TransactionID between 1 and 20 -- maybe??
        and t1.TransactionDesc like 'Transfer from%'
        and t2.TransactionDesc like 'Transfer to%'
        and t2.TransactionID > t1.TransactionID

【讨论】:

谢谢。我已经尝试过类似的东西。由于该表有数百万行,因此性能不是很好。我实际上已经使用 DIFFERENCE 函数将一些东西放在一起,这似乎工作得很好:) 并且索引(日期,金额)可能会带来巨大的改进。

以上是关于识别 SQL 中的账户间转账的主要内容,如果未能解决你的问题,请参考以下文章

PayPal和转账到多个银行账户

关联账户

Java 支付宝支付,退款,单笔转账到支付宝账户(单笔转账到支付宝账户)

事务隔离级别

什么是用于创建程序可用于执行合同付款的转账账户的 Solana 模式?

转账到用户的银行账户