仅在过去日期超过30天时返还帐户余额

时间:2015-02-20 21:06:37

标签: sql oracle

我的表accountsaccount_ID列中有客户ID,在account_balance列中每个ID有多个帐户余额。每个ID还有多个声明日期,列account_statement_date

如果帐户余额大于$ 50.00且过去最近的对帐单日期超过30天,我需要返回ID和帐户余额。

如果帐户余额大于$ 50.00,则会返回ID和帐户余额:

select account_ID, sum(account_balance)
from accounts
where account_balance > 50
group by account_ID

如果帐户余额大于$ 50.00且过去最近的对帐单日期大于30天,如何优化查询以仅返回ID和帐户余额?

4 个答案:

答案 0 :(得分:1)

只需在查询中添加having子句:

select account_ID, sum(account_balance)
from accounts
where account_balance > 50
group by account_ID
having max(account_statement_date) < sysdate - 30;

编辑:

Shankar的评论似乎是正确的。以下修复了它:

select account_ID,
        sum(case when account_balance > 50 then account_balance else 0 end)
from accounts
group by account_ID
having max(account_statement_date) < sysdate - 30;

答案 1 :(得分:1)

我不确定你应该汇总帐户余额。

SELECT * FROM (
    SELECT account_id, account_balance, account_statement_date
         , MAX(account_statement_date) OVER ( PARTITION BY account_id ) AS max_statement_date
      FROM accounts
) WHERE account_balance > 50
    AND account_statement_date = max_statement_date
    AND max_statement_date < TRUNC(SYSDATE-30);

答案 2 :(得分:1)

如果您的数据如下所示:

account_ID  account_statement_date  account_balance
1529        2014-12-01              $40.00
1529        2015-01-01              $60.00
1529        2015-02-01              $65.00 -- < 30 days
2647        2014-12-01              $20.00
2647        2015-01-01              $25.00 -- > 30 days but < $50
3198        2014-12-01              $10.00
3198        2015-01-01              $50.00 -- > 30 days and >= $50

2015-02-01上运行时的正确答案是:

account_ID  account_statement_date  account_balance
3198        2015-01-01              $50.00

然后我认为您想要的查询可能如下所示:

SELECT
   a.account_ID,
   a.account_statement_date,
   a.account_balance
FROM
   (
      SELECT
         row_number() OVER (PARTITION BY account_ID ORDER BY account_statement_date DESC) AS latest,
         account_ID,
         account_statement_date,
         account_balance
      FROM
         accounts
   ) AS a
WHERE
   a.account_statement_date < sysdate - 30
   AND a.latest = 1
   AND a.account_balance >= 50
;

但是,如果你的数据是这样的:

account_ID  account_balance_date account_statement_date  account_balance
1529        2014-12-10           2015-01-01              $40.00
1529        2015-12-16           2015-01-01              $60.00
1529        2015-01-10           2015-02-01              $30.00
1529        2015-01-19           2015-02-01              $65.00 -- < 30 days
2647        2014-12-25           2015-01-01              $20.00
2647        2014-12-30           2015-01-01              $25.00 -- > 30 days
2647        2014-01-02           NULL                    $75.00
2647        2014-01-15           NULL                    $20.00 -- but < $50
3198        2014-12-14           2015-01-01              $20.00
3198        2014-12-30           2015-01-01              $25.00 -- > 30 days
3198        2014-01-09           NULL                    $20.00
3198        2014-01-22           NULL                    $50.00 -- and >= $50!

2015-02-01上运行时的正确答案是:

account_ID  last_account_statement_date  last_account_balance
3198        2015-01-01                   $50.00

然后我认为您想要的查询可能如下所示:

SELECT
   a.account_ID,
   a.account_balance AS last_account_balance,
   (
      SELECT Max(account_statement_date)
      FROM accounts a3
      WHERE
         a1.account_ID = a3.account_ID
         AND account_statement_date IS NOT NULL
   ) AS last_statement_date
FROM
   (
      SELECT
         row_number() OVER (PARTITION BY account_ID ORDER BY account_balance_date DESC) AS latest,
         account_ID,
         account_balance_date,
         account_statement_date,
         account_balance
      FROM
         accounts
   ) AS a
 WHERE
    a.latest = 1 -- the most recent balance by account_balance_date
    AND a.account_balance >= 50
    AND ( -- this clause is optional and may aid or harm performance
       a.account_statement_date IS NULL
       OR a.account_statement_date < sysdate - 30
    )
    AND NOT EXISTS ( -- no statement in the last 30 days
       SELECT *
       FROM
          accounts AS a2
       WHERE
          a.account_ID = a2.accountID
          AND a2.account_statement_date >= sysdate - 30
    )
;

我对30天的部分感到怀疑 - 可能正确的计算将涉及某些日期数学约一个月&#34;从前一个声明日期开始,已知规则用于确定具有不同天数的月数意味着什么。

答案 3 :(得分:0)

我认为这应该对你有用..

select * from
(select account_ID, sum(account_balance) bal, max(account_statement_date) st_date
from accounts
group by account_ID) tab1
where tab1.bal > 50 and tab1.st_date > (sysdate - 30)