2016-08-24 37 views
2

什麼我想要實現的是計算在某種時間線的出現,考慮重疊的事件作爲一個單一的一個,從這樣的領域啓動和使用TSQL:二進制運算符或在TSQL?

Pattern (JSON array of couple of values indicating 
the start day and the duration of the event) 
---------------------------------------------------- 
[[0,22],[0,24],[18,10],[30,3]]  
---------------------------------------------------- 

對於這個例子的結果預計應該是30

我需要的是一個TSQL函數來獲取這個號碼......

即使我不知道它是遵循了正確的道路,我試圖模擬一種BINARY的OR我的數據集的行之間。 一些嘗試後,我成功地把我的數據集弄成這個樣子:

start | length | pattern 
---------------------------------------------------- 
0  | 22  | 1111111111111111111111 
0  | 24  | 111111111111111111111111 
18  | 10  | 000000000000000001111111111 
30  | 3  | 000000000000000000000000000000111 
---------------------------------------------------- 

但現在我不」知道如何在TSQL進行=) 一個解決方案,我說可能是一個二進制或「模式之間「字段獲得這樣的事情:

1111111111111111111111........... 
111111111111111111111111......... 
000000000000000001111111111...... 
000000000000000000000000000000111 
-------------------------------------- 
111111111111111111111111111000111 

是否有可能在TSQL中做到這一點?

也許我只是在這裏複雜的東西你有其他的想法嗎?

不要忘記我只需要結果編號!

謝謝大家

+1

所以你期望的結果是舉辦活動的總天數? – iamdave

+0

我預計至少有一個事件發生的天數總數! – Zakkojo

+0

這裏的預期輸出是什麼? –

回答

2

根據您輸入的日期,你應該能夠做到像下面這樣來計算你的天的事件。

cte用於生成日期表,其開始和結束由兩個日期變量定義。這些將最適合作爲源數據驅動的數據。如果你必須使用編號日期值,你可以簡單地返回,而不是增量遞增日期的數字:

declare @Events table (StartDate date 
         ,DaysLength int 
         ) 
insert into @Events values 
('20160801',22) 
,('20160801',24) 
,('20160818',10) 
,('20160830',3) 

declare @StartDate date = getdate()-30 
     ,@EndDate date = getdate()+30 

;with Dates As 
( 
select DATEADD(day,1,@StartDate) as Dates 
union all 
select DATEADD(day,1, Dates) 
from Dates 
where Dates < @EndDate 
) 
select count(distinct d.Dates) as EventingDays 
from Dates d 
    inner join @Events e 
     on(d.Dates between e.StartDate and dateadd(d,e.DaysLength-1,e.StartDate) 
      ) 
option(maxrecursion 0) 
+0

有趣的代碼,它的工作原理是我用我的真實數據集嘗試,我有一個小問題!是否有可能超過100遞歸的限制? – Zakkojo

+1

對不起,我發現 OPTION(maxrecursion 140) – Zakkojo

+0

@Zakkojo如果您正確設置開始日期和結束日期,您還可以簡單地將'maxrecursion'設置爲'0',以便完全沒有限制。 – iamdave

3

只有總天數,一個事件發生時需要返還。

但我想知道實際計算二進制OR'd模式有多困難。

declare @T table (start int, length int); 

insert into @T values 
(0,22), 
(0,24), 
(18,10), 
(30,3); 

WITH 
DIGITS as (
    select n 
    from (values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) D(n) 
), 
NUMBERS as (
    select (10*d2.n + d1.n) as n 
    from DIGITS d1, DIGITS d2 
    where (10*d2.n + d1.n) < (select max(start+length) from @T) 
), 
CALC as (
    select N.n, max(case when N.n between IIF(T.start>0,T.start,1) and IIF(T.start>0,T.start,1)+T.length-1 then 1 else 0 end) as ranged 
    from @T T 
    cross apply NUMBERS N 
    group by N.n 
) 
select SUM(c.ranged) as total, 
stuff(
(
    select ranged as 'text()' 
    from CALC 
    order by n 
    for xml path('') 
),1,1,'') as pattern 
from CALC c; 

結果:

total pattern 
30  11111111111111111111111111100111 
+0

我無法使其在sql-2008上的生產工作,但感謝您分享您有趣的解決方案! – Zakkojo

相關問題