如果您的数据如下所示:
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 天部分持怀疑态度 - 可能是正确的计算将涉及从上一个报表日期开始的“一个月”的一些日期数学,并有已知的规则来确定不同月份的月份意味着什么天数。