이것은 일반적인 범위 찾기 문제이며 연결이 포함되어 있습니다. 다음 내용이 정확히 맞는 것은 확실하지만 출발점입니다. 커서가 세트 기반 솔루션보다 빠르다는 작은 경우를 제외하고는 커서를 사용하지 않는 것이 가장 좋습니다. 커서 불쾌감이 들기 전에 커서를 사용합니다. . 문제 - 내가 일반적으로 그들을 피하기)
을 나는이 같은 데이터를 작성 그래서 경우 :
CREATE TABLE [dbo].[sourceValues](
[Start] [int] NOT NULL,
[End] [int] NOT NULL,
[Item] [varchar](100) NOT NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[sourceValues] WITH CHECK ADD CONSTRAINT [End_after_Start] CHECK (([End]>[Start]))
GO
ALTER TABLE [dbo].[sourceValues] CHECK CONSTRAINT [End_after_Start]
GO
declare @i int; set @i = 0;
declare @start int;
declare @end int;
declare @item varchar(100);
while @i < 1000
begin
set @start = ABS(CHECKSUM(newid()) % 100) + 1 ; -- "random" int
set @end = @start + (ABS(CHECKSUM(newid()) % 10)) + 2; -- bigger random int
set @item = char((ABS(CHECKSUM(newid())) % 5) + 65); -- random letter A-E
print @start; print @end; print @item;
insert into sourceValues(Start, [End], Item) values (@start , @end, @item);
set @i += 1;
end
그런 다음 나는이 같은 문제를 처리 할 수 있습니다 : 각각의 "시작"을 각각 "끝"을 값의 변화를 나타냅니다 현재 항목의 컬렉션에서 특정 시간에 하나 추가하거나 제거합니다. 아래의 코드에서이 개념을 "이벤트"라는 별칭으로 추가 또는 제거합니다. 각 시작 또는 끝은 시간과 같으므로 용어 "틱"을 사용합니다. 이벤트 시간 (시작 및 종료)별로 정렬 된 모든 이벤트의 컬렉션을 만들면 재생중인 모든 항목의 메모리 내장 테이블에서 실행 집계를 유지하면서 반복 할 수 있습니다. 눈금 값이 변경, 내가 그 집계의 스냅 샷을 할 때마다 :
declare @tick int;
declare @lastTick int;
declare @event varchar(100);
declare @item varchar(100);
declare @concatList varchar(max);
declare @currentItemsList table (Item varchar(100));
create table #result (Start int, [End] int, Items varchar(max));
declare eventsCursor CURSOR FAST_FORWARD for
select tick, [event], item from (
select start as tick, 'Add' as [event], item from sourceValues as adds
union all
select [end] as tick, 'Remove' as [event], item from sourceValues as removes
) as [events]
order by tick
set @lastTick = 1
open eventsCursor
fetch next from eventsCursor into @tick, @event, @item
while @@FETCH_STATUS = 0
BEGIN
if @tick != @lastTick
begin
set @concatList = ''
select @concatList = @concatlist + case when len(@concatlist) > 0 then '-' else '' end + Item
from @currentItemsList
insert into #result (Start, [End], Items) values (@lastTick, @tick, @concatList)
end
if @event = 'Add' insert into @currentItemsList (Item) values (@item);
else if @event = 'Remove' delete top (1) from @currentItemsList where Item = @item;
set @lastTick = @tick;
fetch next from eventsCursor into @tick, @event, @item;
END
close eventsCursor
deallocate eventsCursor
select * from #result order by start
drop table #result
이 특별한 경우에 커서를 사용하여 단 하나의 누계 문제와 같은 데이터를 통해 "통과"할 수 있습니다. Itzik Ben-Gan은 SQL 2005 서적에서이 점에 대한 훌륭한 예를 보여줍니다. 이 것
실행중인 SQL Server 버전은 무엇입니까? – Sung
얼마나 많은 항목이 겹칠 수 있습니까? (즉, 항상 2, a 및 b 또는 임의 숫자 일 수 있습니까?) – onupdatecascade
SQL Server 2008 및 중복되는 항목 수는 누구나 가능합니다. – river0