Dies führt zu den gewünschten Ergebnissen. Nicht so elegant wie Gordon, aber es lässt Lücken in Daten und Doppeltermine zu.
Wenn Sie eine Kalender-/Tally-Tabelle haben, kann die Cte-Logik entfernt werden.
Beispiel
Declare @YourTable Table ([AsOfDate] Date,[SecurityID] varchar(50),[IsHeld] bit)
Insert Into @YourTable Values
('2017-05-19','S1',1)
,('2017-05-20','S1',1)
,('2017-05-21','S1',1)
,('2017-05-22','S1',1)
,('2017-05-23','S1',0)
,('2017-05-24','S1',0)
,('2017-05-25','S1',0)
,('2017-05-26','S1',1)
,('2017-05-27','S1',1)
,('2017-05-28','S1',1)
,('2017-05-29','S1',0)
,('2017-05-30','S1',0)
,('2017-05-31','S1',1)
;with cte1 as (Select D1=min(AsOfDate),D2=max(AsOfDate) From @YourTable)
,cte2 as (
Select Top (DateDiff(DAY,(Select D1 from cte1),(Select D2 from cte1))+1)
D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),(Select D1 from cte1))
,R=Row_Number() over (Order By (Select Null))
From master..spt_values n1,master..spt_values n2
)
Select [SecurityID]
,[StartDate] = min(D)
,[EndDate] = max(D)
From (
Select *,Grp = dense_rank() over (partition by securityId order by asofdate)-R
From @YourTable A
Join cte2 B on AsOfDate=B.D
Where IsHeld=1
) A
Group By [SecurityID],Grp
Order By min(D)
Returns
SecurityID StartDate EndDate
S1 2017-05-19 2017-05-22
S1 2017-05-26 2017-05-28
S1 2017-05-31 2017-05-31
Welche Version von SQL Server? – Shawn
@Shawn sein Microsoft SQL Server 2008 (SP4) – Ram