平衡否定3个月

时间:2017-01-15 00:10:24

标签: sql oracle aggregate aggregate-functions

我有3张桌子。帐户。 Trans and Balance。

假设帐户只有2个帐户。帐号1和2。

他们都在Trans Table中有多个交易。

Trans表中的Sum(Amount)等于每个帐户在任何给定时间的余额。

例如:账户1和账户2都有50美元。账户1的交易价格为100美元,账户2的交易价格仅为35美元。

现在,账户1的余额为负50美元。假设他存了20美元。无论如何,平衡仍然是负面的。

我需要一个查询,从今天的日期起连续3个月或更长时间内检查余额为负数。 (所以每当我运行它时都是sysdate)。虽然他有20美元的存款,但余额仍然是负数。

当我使用trans表中的transdate或来自余额表的lastupdate作为3个月标准时,上述帐户不会被提取。虽然,它是负面的,但它看到了交易。

我想知道我怎样才能查询显示帐号和余额的位置,只有在连续3个月或更长时间内显示为负数时,无论交易何时发生。

列:

 Account Table has AccountID
 Trans Table has AccountID, Amount, TransDate
 Balance Table has AccountID, Balance, LastUpdate 

由于

更新

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

现在,他的帐户出现了负数 - 2016年10月7日20美元。

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

他的帐户仍然是负面的。如果我今天(2017年1月15日)或之后运行查询,他的帐户应该被拿起,因为他仍然有至少90天的负余额。

Balance Table

每个帐户只保留1条记录。 截至今天,它显示以下内容:

AccountID    Balance    LastUpdate
1            -10        12/01/2016

LastUpdate与该帐户的Trans Table中最后一个交易日期相同。

即使昨天最后一笔存款出现但帐户仍为负数,我仍然会疯狂地找到90天或以上为负数的账户。我有50,000个帐户需要这样做....

1 个答案:

答案 0 :(得分:0)

我们将为所有交易计算运行余额。然后,我们将为每个帐户选择最近的交易,并将其过滤到仅包含以下内容的帐户:

  1. 最近的交易超过90天;或
  2. 过去90天的最高余额小于0.
  3. ;
    WITH running_total AS (
    
            SELECT   t.AccountID
                    ,t.Transdate
                    ,t.Amount
                    ,SUM(t.Amount) OVER (PARTITION BY t.AccountID ORDER BY t.Transdate ROWS UNBOUNDED PRECEDING) AS RunningTotal
            FROM (
                    -- Aggregate transctions by Account and Date
                    SELECT   t.AccountID
                            ,t.Transdate
                            ,SUM(t.Amount) AS Amount
                    FROM Trans
                    GROUP BY t.AccountID
                            ,t.Transdate
                    ) t
    
    )
    
    SELECT *
    FROM running_total rt
    WHERE 
    -- Most recent transaction
    rt.Transdate = (
            SELECT MAX(Transdate)
            FROM running_total
            WHERE AccountID = rt.AccountID
    )
    -- Current balance is negative
    AND rt.RunningTotal < 0
    
    -- Get maximum balance for all transctions in the past 90 days
    -- If none found (most recent transaction more than 90 days old),
    -- substitute -1
    AND COALESCE((
            SELECT MAX(RunningTotal)
            FROM running_total
            WHERE AccountID = rt.AccountID
            AND Transdate >= DATEADD(DAY, -90, GETDATE())
    ), -1) < 0