我的表accounts
在account_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和帐户余额?
答案 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)