2017-01-16 7 views
0

У меня есть 3 стола. Счет. Транс и Баланс.Отрицательный баланс

Сумма в таблице Trans равна балансу в любой момент времени для каждой учетной записи.

Мне нужен запрос, который проверяет, что баланс отрицательный для последовательных 3 месяцев или более с сегодняшней даты. (так что sysdate всякий раз, когда я запускаю это).

Мне было интересно, как я могу запросить, где будет отображаться номер счета и баланс, только если он будет отрицательным в течение 3 или более месяцев независимо от того, когда произойдет транзакция.

Таблицы:

Trans Table 
Select * from trans where accountid = 1; 

Transdate Merchant Amount AccountID 
10/1/16 Employer 50  1 
10/4/16 Walmart  -20  1 
10/7/16 Kroger  -50  1 

Теперь его счет пошел отрицательный - $ 20 на 10/7/2016.

Transdate Merchant Amount AccountID 
12/01/16 Employer 10  1 

Его счет по-прежнему отрицательный. Если я запустил запрос сегодня (01/16/2017) или позже, его учетную запись нужно получить, потому что он по-прежнему имеет отрицательный баланс не менее 90 дней.

Balance Table 

Он хранит только 1 запись на одну учетную запись. На сегодняшний день, это показывает следующее:

AccountID Balance LastUpdate 
1   -10  12/01/2016 

LastUpdate является тот же день, как на последнюю дату совершения операции в Trans таблице для этого счета.

+0

Привет, сколько записей в каждой учетной записи (в день или в месяц)? – hmmftg

+0

10-15 транзакций на счет. И 50 000 счетов все вместе. – Amir

ответ

2

Попробуйте следующее. Верхняя часть просто создает некоторые тестовые данные ...

WITH 
trans (transdate,merchant,amount,accountID) 
AS 
(SELECT sysdate-100,'A',100,1 FROM dual UNION ALL 
    SELECT sysdate-99,'B',-101,1 FROM dual UNION ALL 
    SELECT sysdate-91,'C',-50,1 FROM dual UNION ALL 
    SELECT sysdate-10,'D',30,1 FROM dual UNION ALL 
    SELECT sysdate-100,'E',100,2 FROM dual UNION ALL 
    SELECT sysdate-99,'F',-100,2 FROM dual UNION ALL 
    SELECT sysdate-91,'G',-50,2 FROM dual UNION ALL 
    SELECT sysdate-10,'H',200,2 FROM dual UNION ALL 
    SELECT sysdate-10,'I',100,3 FROM dual UNION ALL 
    SELECT sysdate-9,'J',-50,3 FROM dual UNION ALL 
    SELECT sysdate-8,'K',-75,3 FROM dual 
) 
SELECT DISTINCT 
accountId 
FROM 
(SELECT 
    accountid 
    ,transdate 
    ,amount 
    --get the maximum balance in the dataset 
    ,MAX(balance) OVER (PARTITION BY accountID) max_balance 
    FROM 
    --this query gets raw transaction data and calculates cumulative balance 
    (SELECT 
    accountid 
    ,transdate 
    ,amount 
    --cumulative balance 
    ,SUM(amount) OVER (PARTITION BY accountID ORDER BY transdate) balance 
    --works the dateof the next transaction - ths determines how long the balance is current 
    ,LEAD(transdate) OVER (PARTITION BY accountID ORDER BY transdate) - 1 bal_end_date 
    FROM 
    trans 
    ) 
    WHERE 1=1 
    --only interested in balances that are 'current' in the past three months 
    AND bal_end_date >= ADD_MONTHS(sysdate,-3) 
) 
WHERE 1=1 
--only want accounts where the maximum balance is negative 
AND max_balance < 0 
; 
+0

Обратите внимание, что мое решение можно улучшить, используя таблицу балансов, чтобы ограничить анализ учетными записями, которые в настоящее время имеют отрицательный баланс. По мере необходимости запрос должен оглядываться на все транзакции для учетной записи для расчета баланса в любой момент времени - это пустая трата усилий для этого для учетных записей, где мы знаем, что текущий баланс положительный. –

+0

Любые отзывы об этом? –

+0

Это работает. Благодаря! – Amir