, 당신은 전용 데이터베이스 당이 한 번해야하는 "도우미"테이블을 설정해야합니다 단일 열에 1에서 8000까지의 값이 포함되어 있습니다. CTE를 사용하여 동일하게 수행 할 수 있지만 SQL Server 버전을 말하는 것은 아니므로이 기능은 모두 작동하며이 기능을 여러 번 실행하면 더 좋습니다.
이 시도 :
DECLARE @Calls table (rowID int not null primary key identity(1,1)
,EvId int not null
,CallId varchar(36)
,rowDateTime datetime
)
SET NOCOUNT ON
INSERT INTO @Calls VALUES (0,'df1cbc93-5cf3-402a-940b-4441f6a7ec5c',' 7/9/2008 8:12:56 PM')
INSERT INTO @Calls VALUES (1,'df1cbc93-5cf3-402a-940b-4441f6a7ec5c',' 7/9/2008 8:13:07 PM')
INSERT INTO @Calls VALUES (0,'ec1c2078-1765-4377-9126-6f26fe33e4a9','7/10/2008 4:33:10 PM')
INSERT INTO @Calls VALUES (10,'ec1c2078-1765-4377-9126-6f26fe33e4a9','7/10/2008 4:33:13 PM')
INSERT INTO @Calls VALUES (1,'ec1c2078-1765-4377-9126-6f26fe33e4a9','7/10/2008 4:33:13 PM')
INSERT INTO @Calls VALUES (0,'a3c3b9a0-a23b-4dda-b4e4-e82f0209c94d','7/10/2008 4:33:13 PM')
INSERT INTO @Calls VALUES (10,'a3c3b9a0-a23b-4dda-b4e4-e82f0209c94d','7/10/2008 4:33:15 PM')
INSERT INTO @Calls VALUES (1,'a3c3b9a0-a23b-4dda-b4e4-e82f0209c94d','7/10/2008 4:33:15 PM')
INSERT INTO @Calls VALUES (0,'d23f393d-0272-445a-8670-3f71b016174e','7/10/2008 4:33:15 PM')
INSERT INTO @Calls VALUES (10,'d23f393d-0272-445a-8670-3f71b016174e','7/10/2008 4:33:17 PM')
INSERT INTO @Calls VALUES (1,'d23f393d-0272-445a-8670-3f71b016174e','7/10/2008 4:33:17 PM')
--I added more test data, to hit more cases
INSERT INTO @Calls VALUES (0,'111111111111111111111111111111111111','7/10/2008 4:10:00 PM')
INSERT INTO @Calls VALUES (10,'111111111111111111111111111111111111','7/10/2008 4:11:00 PM')
INSERT INTO @Calls VALUES (1,'111111111111111111111111111111111111','7/10/2008 4:11:00 PM')
INSERT INTO @Calls VALUES (0,'222222222222222222222222222222222222','7/10/2008 4:15:00 PM')
INSERT INTO @Calls VALUES (10,'222222222222222222222222222222222222','7/10/2008 4:16:00 PM')
INSERT INTO @Calls VALUES (1,'222222222222222222222222222222222222','7/10/2008 4:16:00 PM')
INSERT INTO @Calls VALUES (0,'333333333333333333333333333333333333','7/10/2008 4:09:00 PM')
INSERT INTO @Calls VALUES (10,'333333333333333333333333333333333333','7/10/2008 4:18:00 PM')
INSERT INTO @Calls VALUES (1,'333333333333333333333333333333333333','7/10/2008 4:18:00 PM')
INSERT INTO @Calls VALUES (0,'444444444444444444444444444444444444','7/10/2008 4:13:00 PM')
INSERT INTO @Calls VALUES (10,'444444444444444444444444444444444444','7/10/2008 4:14:00 PM')
INSERT INTO @Calls VALUES (1,'444444444444444444444444444444444444','7/10/2008 4:14:00 PM')
INSERT INTO @Calls VALUES (0,'555555555555555555555555555555555555','7/10/2008 4:13:00 PM')
SET NOCOUNT OFF
DECLARE @StartRange datetime
DECLARE @EndRange datetime
SET @StartRange='7/10/2008 4:12:00 PM'
SET @EndRange ='7/10/2008 4:15:00 PM'
SET @EndRange=DATEADD(mi,1,@EndRange)
--this lists the match time and each calls details in progress at that time
SELECT
DATEADD(mi,n.Number-1,c.StartTime) AS 'TimeOfMatch'
,c.CallID
,c.StartTime,c.EndTime
FROM (SELECT --this derived table joins together the start and end dates into a single row, filtering out rows more than 90 minutes before the start range (if calls are longer than 90 minutes, increase this) and filters out any rows after the end date (will consider call done at end date then)
CallID, MIN(rowDateTime) AS StartTime, CASE WHEN MAX(rowDateTime)=MIN(rowDateTime) THEN @EndRange ELSE MAX(rowDateTime) END AS EndTime
FROM @Calls
WHERE rowDateTime>=DATEADD(mi,-90,@StartRange) --AND rowDateTime<[email protected]
GROUP BY CallID
) c
INNER JOIN Numbers n ON DATEDIFF(mi,c.StartTime,c.EndTime)+1>=n.Number
WHERE DATEADD(mi,n.Number-1,c.StartTime)>[email protected] AND DATEADD(mi,n.Number-1,c.StartTime)<@EndRange
ORDER BY 1
--this lists just the match time and the call count
SELECT
DATEADD(mi,n.Number-1,c.StartTime) AS 'TimeOfMatch'
,c.CallID
,c.StartTime,c.EndTime
FROM (SELECT --this derived table joins together the start and end dates into a single row, filtering out rows more than 90 minutes before the start range (if calls are longer than 90 minutes, increase this) and filters out any rows after the end date (will consider call done at end date then)
CallID, MIN(rowDateTime) AS StartTime, CASE WHEN MAX(rowDateTime)=MIN(rowDateTime) THEN @EndRange ELSE MAX(rowDateTime) END AS EndTime
FROM @Calls
WHERE rowDateTime>=DATEADD(mi,-90,@StartRange) --AND rowDateTime<[email protected]
GROUP BY CallID
) c
INNER JOIN Numbers n ON DATEDIFF(mi,c.StartTime,c.EndTime)+1>=n.Number
WHERE DATEADD(mi,n.Number-1,c.StartTime)>[email protected] AND DATEADD(mi,n.Number-1,c.StartTime)<@EndRange
ORDER BY 1
여기 출력입니다 :
TimeOfMatch CallID StartTime EndTime
----------------------- ------------------------------------ ----------------------- -----------------------
2008-07-10 16:12:00.000 333333333333333333333333333333333333 2008-07-10 16:09:00.000 2008-07-10 16:18:00.000
2008-07-10 16:13:00.000 333333333333333333333333333333333333 2008-07-10 16:09:00.000 2008-07-10 16:18:00.000
2008-07-10 16:13:00.000 444444444444444444444444444444444444 2008-07-10 16:13:00.000 2008-07-10 16:14:00.000
2008-07-10 16:13:00.000 555555555555555555555555555555555555 2008-07-10 16:13:00.000 2008-07-10 16:16:00.000
2008-07-10 16:14:00.000 555555555555555555555555555555555555 2008-07-10 16:13:00.000 2008-07-10 16:16:00.000
2008-07-10 16:14:00.000 444444444444444444444444444444444444 2008-07-10 16:13:00.000 2008-07-10 16:14:00.000
2008-07-10 16:14:00.000 333333333333333333333333333333333333 2008-07-10 16:09:00.000 2008-07-10 16:18:00.000
2008-07-10 16:15:00.000 333333333333333333333333333333333333 2008-07-10 16:09:00.000 2008-07-10 16:18:00.000
2008-07-10 16:15:00.000 555555555555555555555555555555555555 2008-07-10 16:13:00.000 2008-07-10 16:16:00.000
2008-07-10 16:15:00.000 222222222222222222222222222222222222 2008-07-10 16:15:00.000 2008-07-10 16:16:00.000
(10 row(s) affected)
TimeOfMatch
----------------------- -----------
2008-07-10 16:12:00.000 1
2008-07-10 16:13:00.000 3
2008-07-10 16:14:00.000 3
2008-07-10 16:15:00.000 3
(4 row(s) affected)
당신은 rowDateTime + CallId에 복합 인덱스가 필요합니다. 그러나 최상의 성능을 위해 단일 호출의 시작 날짜와 종료 날짜가 모두 포함 된 새 테이블 (startdate + CallId에 클러스터 된 인덱스)을 만든 경우 (시작 날짜가 EvId = 0 인 삽입을 사용하는 경우와 EvId = 1 업데이트 종료 날짜)이 새 테이블을 사용하여 파생 테이블을 제거 할 수 있습니다.
각 통화마다 고유 한 식별자가 있습니까? –
다음을보십시오 .http : //stackoverflow.com/questions/781895/checking-for-time-range-overlap-the-watchman-problem-sql 이것은 오버랩을 계산하는 방법을 보여줍니다. – pjp
"오버랩" 일부는 동일한 시작/종료 지점을가집니다. 어쨌든, 샘플 코드에 대한 최신 편집을 참조하십시오 ... –