2015-12-09 4 views
0

У меня есть куча банковских транзакций в таблице в SQL.Определить межбанковские переводы в SQL

Пример: http://sqlfiddle.com/#!6/6b2c8/1/0

мне нужно определить операции, которые сделаны между этими 2-х соединенными счетами. Таблица учетных записей (не показана) связывает эти 2 учетные записи с одним источником (пользователем).

Например: У меня есть обычная учетная запись и сберегательный счет. Время от времени я могу перевести деньги из своей повседневной учетной записи на мой сберегательный счет (или наоборот).

Описание операций, как правило, аналогично (перенос на ххх/перевод с ххх), обычно в тот же день, и, очевидно, та же сумма в долларах.

EDIT: теперь у меня есть следующий запрос (упрощенных вниз), который работает для некоторых сценариев

В принципе, я создал 2 временные таблицы со всеми изъятий и депозитов, которые отвечают определенным критериям. Затем я объединяю их, основываясь на нескольких требованиях (одинаковая сумма транзакции, другая учетная запись и т. Д.). Затем, используя функцию ROW_NUMBER, я заказывал, какие из них скорее всего будут транзакциями между счетами.

теперь у меня есть проблема, когда, если, например:

$ 100 переносится из счета А на счет Б

$ 100 Переданные из счета B на счет C

Мой запрос будет соответствовать передаче между Учетные записи A и C, то для учетной записи B существует только одна транзакция, и она не будет сопоставлена. Таким образом, по существу, вместо того чтобы получать 2 ряда назад (2 депозиты, выстроились с 2-мя снятия), я получаю только 1 строку (1 депозит, 1 вывода), для передачи от А до Б :(

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 
+0

Спасибо. Я уже пытался что-то подобное. это не очень поскольку таблица имеет миллионы строк. Я на самом деле что-то выбросил, используя функцию DIFFERENCE, которая, кажется, работает достаточно хорошо :) – TaylorN

+0

И индекс по (дата, сумма), вероятно, будет e огромное улучшение. – shawnt00

Смежные вопросы