通過稍微調整輸入數據並略微調整我們如何定義需求,生成預期結果變得非常簡單。
首先,我們調整您的date
值,以便唯一變化的是月和年 - 日子都是一樣的。我選擇這樣做,我爲每個值添加1天。事實上,這產生了一個月提前的結果在這裏並不重要,因爲所有的價值都是相似的變化,所以每月的關係保持不變。然後,我們介紹一個數字表 - 在這裏,我假設一個小的固定表就足夠了。如果它不適合您的需求,您可以輕鬆地在線查找示例以創建可用於此查詢的大型固定數字表。
最後,我們重鑄問題陳述。我們不是試圖計算幾個月,而是問「什麼是最小月數,大於等於零,我需要從當前行返回,找到一個非1結果的行?」。因此,我們產生這樣的查詢:
declare @t table (id int not null,ind int not null,lvl varchar(13) not null,
result int not null,date date not null)
insert into @t(id,ind,lvl,result,date) values
(1 ,1,'a',3,'20170131'), (2 ,1,'a',3,'20170228'), (3 ,1,'a',1,'20170331'),
(4 ,1,'a',1,'20170430'), (5 ,1,'a',1,'20170531'), (6 ,1,'b',1,'20170131'),
(7 ,1,'b',3,'20170228'), (8 ,1,'b',3,'20170331'), (9 ,1,'b',1,'20170430'),
(10,1,'b',1,'20170531'), (11,2,'a',3,'20170131'), (12,2,'a',1,'20170228'),
(13,2,'a',3,'20170331'), (14,2,'a',1,'20170430'), (15,2,'a',3,'20170531')
;With Tweaked as (
select
*,
DATEADD(day,1,date) as dp1d
from
@t
), Numbers(n) as (
select 0 union all select 1 union all select 2 union all select 3 union all select 4
union all
select 5 union all select 6 union all select 7 union all select 8 union all select 9
)
select
id, ind, lvl, result, date,
COALESCE(
(select MIN(n) from Numbers n1
inner join Tweaked t2
on
t2.ind = t1.ind and
t2.lvl = t1.lvl and
t2.dp1d = DATEADD(month,-n,t1.dp1d)
where
t2.result != 1
),
1) as [BadResultRemainsFor%Months]
from
Tweaked t1
的COALESCE
只是有對付邊緣的情況下,如您1,b
數據,在沒有前一行與非1的結果。
結果:
id ind lvl result date BadResultRemainsFor%Months
----------- ----------- ------------- ----------- ---------- --------------------------
1 1 a 3 2017-01-31 0
2 1 a 3 2017-02-28 0
3 1 a 1 2017-03-31 1
4 1 a 1 2017-04-30 2
5 1 a 1 2017-05-31 3
6 1 b 1 2017-01-31 1
7 1 b 3 2017-02-28 0
8 1 b 3 2017-03-31 0
9 1 b 1 2017-04-30 1
10 1 b 1 2017-05-31 2
11 2 a 3 2017-01-31 0
12 2 a 1 2017-02-28 1
13 2 a 3 2017-03-31 0
14 2 a 1 2017-04-30 1
15 2 a 3 2017-05-31 0
進行調整的另一種方法是使用一個DATEADD
/DATEDIFF
對到對的日期執行 「地板」 操作:
DATEADD(month,DATEDIFF(month,0,date),0) as dp1d
它將所有日期值重置爲本月的第一個月,而不是下一個月。這對你來說可能更加「自然」,或者你的原始數據中可能已經有了這樣的值。
難道我們保證所有'日期'值都是日期,並且每個月的最後一天都是? –
@Damien_The_Unbeliever是的,它將永遠是每個月的最後一天! – Flesym