我尝试过使用ROW_NUMBER,但还没有得到它。关于实现这一目标的最佳方法的任何想法。
我希望找到:
- What month did they first cash flow.
- What month did they average 3 months cash flow.
示例数据: 办公室,平衡&年月
------------------------------
| Office | Balance | YrMo |
| 12 | 111 | 201510 |
| 12 | 222 | 201511 |
| 12 | -444 | 201512 |
| 12 | -777 | 201601 |
| 12 | 555 | 201602 |
| 12 | 666 | 201603 |
| 12 | -888 | 201604 |
| 12 | 777 | 201605 |
| 40 | -555 | 201510 |
| 40 | -200 | 201511 |
| 40 | 0 | 201512 |
| 40 | 100 | 201601 |
| 40 | -555 | 201602 |
| 40 | 666 | 201603 |
| 40 | 777 | 201604 |
| 40 | 888 | 201605 |
| 40 | 999 | 201606 |
第一个正余额将是:
-office 12 , Balance 111 , YrMo 201510
-office 40 , Balance 100 , YrMo 201601
办公室第一个月平均3个正余额:
-office 40 , Balance 999 , YrMo 201606
这是#test表脚本:
IF OBJECT_ID('tempdb..#test') IS NOT NULL
DROP TABLE #test
GO
CREATE TABLE #test (office INT , Balance INT, YrMo INT ) ;
INSERT INTO #test VALUES (12 , 111 , 201510) ;
INSERT INTO #test VALUES (12 , 222 , 201511) ;
INSERT INTO #test VALUES (12 , -444 , 201512) ;
INSERT INTO #test VALUES (12 , -777 , 201601) ;
INSERT INTO #test VALUES (12 , 555 , 201602) ;
INSERT INTO #test VALUES (12 , 666 , 201603) ;
INSERT INTO #test VALUES (12 , -888 , 201604) ;
INSERT INTO #test VALUES (12 , 777 , 201605) ;
INSERT INTO #test VALUES (40 , -555 , 201510) ;
INSERT INTO #test VALUES (40 , -200 , 201511) ;
INSERT INTO #test VALUES (40 , 0 , 201512) ;
INSERT INTO #test VALUES (40 , 100 , 201601) ;
INSERT INTO #test VALUES (40 , -555 , 201602) ;
INSERT INTO #test VALUES (40 , 666 , 201603) ;
INSERT INTO #test VALUES (40, 777 , 201604) ;
INSERT INTO #test VALUES (40 , 888 , 201605) ;
INSERT INTO #test VALUES (40 , 999 , 201606) ;
提前致谢
答案 0 :(得分:1)
;with cteFirst as (
Select *
,FirstPos=Row_Number() over (Partition By Office Order By YrMo,Balance) from #Test Where Balance>0
),
cteCons as (
Select *
,TestCons=Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),1,0) over (Partition By Office Order By YrMo)
+Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),2,0) over (Partition By Office Order By YrMo)
+Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),3,0) over (Partition By Office Order By YrMo)
from #Test
)
Select *,Status='First Positive' from cteFirst where FirstPos=1
Union All
Select *,Status='3 Cons' from cteCons where TestCons=3
返回
office Balance YrMo FirstPos Status
12 111 201510 1 First Positive
40 100 201601 1 First Positive
40 999 201606 3 3 Consequtive
答案 1 :(得分:1)
我又添了一个例子。这个陷阱在日期中存在差距。
如果要查看所有标志以及数据如何进展,请删除 - 之前选择*来自cteFinal Order by Office,YrMo
我添加了另一个办公室,其中有3个连续的正余额,但月份不是(没有6月)。通知Office 99无法满足连续月份标准
office Balance YrMo
99 199 201605
99 299 201607
99 399 201608
更新的查询如下
;with cteBase as (
Select *
,RowNr = Row_Number() over (Partition By Office Order By Office,YrMo,Balance)
,MthSeq = case when cast(YrMo as int)-Lag(YrMo,1,YrMo-1) over (Partition By Office Order By YrMo) in (1,89) then 1 else 0 end
,IsPos = IIf(Balance>0,1,null)
from #Test
)
,cteFinal as (
Select *
,PosRowNr = min(RowNr*IsPos) over (Partition By Office Order By RowNr)
,TestCons = MthSeq * (
Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),1,0) over (Partition By Office Order By YrMo)
+Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),2,0) over (Partition By Office Order By YrMo)
+Lag(IIf(IIf(sign(balance)=1,1,0)=1,1,0),3,0) over (Partition By Office Order By YrMo)
)
From cteBase
)
--Select * from cteFinal Order by Office,YrMo
Select Office
,Balance
,YrMo
,Status = IIf(RowNr=PosRowNr,'First Positive','')+IIf(TestCons=3,'Consecutive Months','')
From cteFinal
Where TestCons=3 or RowNr=PosRowNr
Order by Status Desc,Office,YrMo
结果
Office Balance YrMo Status
12 111 201510 First Positive
40 100 201601 First Positive
99 199 201605 First Positive
40 999 201606 Consecutive Months