Select * from Balance;
它有AccountID,ClosingDate和Balance。
每个月都有一个条目。例如:
AccountID ClosingDate Balance
123 1/19/2017 -3.00
123 12/19/2016 -2.50
123 11/19/2016 -2.50
另一个帐户
AccountID ClosingDate Balance
456 1/16/2017 -3.00
456 12/16/2016 2.00
456 11/16/2016 -2.50
最后一个例子:
AccountID ClosingDate Balance
789 1/11/2017 -9.00
789 12/11/2016 -2.00
789 11/11/2016 -5.50
我想编写一个查询,生成连续3个语句周期为负数的帐户列表。请记住,所有这些日期的截止日期都不同。查询不应该选择''''帐号。大约有100,000个账户是负面的。但是,我是否需要找到它们是否连续3个月都是负面的。
我需要帐号和最新余额作为输出。但是,如果查询最新的余额很困难,那么只需帐号即可。
由于
答案 0 :(得分:1)
如果您的dbms支持窗口函数,请使用lead
和lag
获取下一个和上一个余额first_value
以获得每个值的最新余额。然后获得具有最新余额的帐户,其中当前行的余额,下一行的余额和前一行的余额为< 0
with cte as (select t.*,
lead(balance) over(partition by accountid order by closingdate) as next_balance,
lag(balance) over(partition by accountid order by closingdate) as prev_balance,
first_value(balance) over(partition by accountid order by closingdate desc) as latest_balance
from t)
select distinct accountid, latest_balance
from cte
where balance < 0 and next_balance < 0 and prev_balance < 0
编辑:解释它的工作原理。让我用你的样本数据来展示它。
123 1/19/2017 -3.00 --balance = -3.00, previous_balance = -2.50, next_balance = null
123 12/19/2016 -2.50 --balance = -2.50, previous_balance = -2.50, next_balance = -3.00
123 11/19/2016 -2.50 --balance = -2.50, previous_balance = null, next_balance = -2.50
where balance < 0 and next_balance < 0 and prev_balance < 0
- 2016年12月19日的行符合此指标连续3个月的负余额标准,并在结果中返回。 first_value(balance) over(partition by accountid order by closingdate desc)
- 返回截至每个帐户最新日期的余额。您可以使用此说明来了解它对其他accountid的作用。
Edit_2:要获得连续7个月或更长时间的负余额的帐户,请使用
WITH CTE AS
(SELECT T.*,
FIRST_VALUE(BALANCE) OVER(PARTITION BY ACCOUNTID ORDER BY CLOSINGDATE DESC) AS LATEST_BALANCE ,
ROW_NUMBER() OVER(PARTITION BY ACCOUNTID ORDER BY CLOSINGDATE) -
ROW_NUMBER() OVER(PARTITION BY ACCOUNTID, SIGN(BALANCE) ORDER BY CLOSINGDATE) AS GRP
FROM T
)
,COUNTS AS
(SELECT C.*,
SUM(CASE WHEN BALANCE < 0 THEN 1 ELSE 0 END) OVER(PARTITION BY ACCOUNTID,GRP ORDER BY CLOSINGDATE) AS CONSECUTIVE_COUNT
FROM CTE C
)
SELECT DISTINCT ACCOUNTID, LATEST_BALANCE
FROM COUNTS
WHERE CONSECUTIVE_COUNT >= 7
或者,如果您准备编写冗长的查询,请使用lead
和lag
函数中的可选参数来向前看或回顾n
行。在这里,您回顾并向前看每行3行。
with cte as (select t.*,
lead(balance,1) over(partition by accountid order by closingdate) as next_balance_1,
lead(balance,2) over(partition by accountid order by closingdate) as next_balance_2,
lead(balance,3) over(partition by accountid order by closingdate) as next_balance_3,
lag(balance,1) over(partition by accountid order by closingdate) as prev_balance_1,
lag(balance,2) over(partition by accountid order by closingdate) as prev_balance_2,
lag(balance,3) over(partition by accountid order by closingdate) as prev_balance_3,
first_value(balance) over(partition by accountid order by closingdate desc) as latest_balance
from t)
select distinct accountid, latest_balance
from cte
where balance < 0
and next_balance_1 < 0 and next_balance_2 < 0 and next_balance_3 < 0
and prev_balance_1 < 0 and prev_balance_2 < 0 and prev_balance_3 < 0