SQL 中的二元运算符 OR?

Binary operator OR in 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 函数来获取这个数字...

即使我不确定要遵循的路径是否正确,我也在尝试在我的数据集的行之间模拟一种二进制或。 经过一些尝试,我设法将我的数据集变成了这样的东西:

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

但现在我不知道如何在 TSQL 中继续 =) 正如我所说的解决方案可以是 "pattern" 字段之间的二进制或以获得类似这样的东西:

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

可以在 TSQL 中实现吗?

也许我只是把事情复杂化了你有其他想法吗?

别忘了我只需要结果编号!!!

谢谢大家

根据您输入的日期,您应该能够执行类似以下操作来计算您的活动天数。

cte 用于生成 table 日期,其开始和结束由两个日期变量定义。这些最适合作为从源数据驱动的数据。如果您必须使用带编号的日期值,您可以简单地 return 递增数字而不是递增日期:

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)

只需要返回事件发生的总天数。

但我想知道实际计算二进制 OR 模式有多难。

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