2010-02-12 8 views
0

나는 일정 범위의 날짜를 생성하기 위해 CTE를 사용하고 있습니다.날짜 사이의 행

12/02/2010 10:00:00 12/02/2010 10:59:59 
12/02/2010 11:00:00 12/02/2010 11:59:59 
12/02/2010 12:00:00 12/02/2010 12:59:59 

나는 엄청난 양의 날짜가 포함 된 색인 된보기에이 항목을 남겼다. 내가 날짜 사이에 계산을 위해 두 가지 옵션이 있습니다

거짓에 대한 사실에 대한

1) 내가 SUM 것이다 (경우)는 시작과 끝 날짜 사이 인 경우 테스트 할 log_date을 테스트 + 1, 0 범위 - 그래서 결과가 없으면 항상 '0'이됩니다.

12/02/2010 10:00:00 12/02/2010 10:59:59 0 
12/02/2010 11:00:00 12/02/2010 11:59:59 1 
12/02/2010 12:00:00 12/02/2010 12:59:59 0 

2) 날짜 범위 당 WHERE 절을 사용하여 계산할 수 있습니다 (*). 당신은 1) 기대 효과가 있지만 성능에 엄청난 오버 헤드가 하듯이

12/02/2010 11:00:00 12/02/2010 11:59:59 1 

2) 가능성이 8,000퍼센트 더 efficent하지만 지정한 날짜 범위 사이에 널 (null) 결과를 반환하는 필터를 적용 할 범위를 반환하지 .

효과적인 WHERE 절을 사용하지만 '0'으로 자세하게 설명하는 날짜 범위 행을 유지하는 방법이 있습니까?

SELECT  [LABEL], [Display Start Date], [Display End Date], 
        COUNT(dbo.vCallLog.line_id) AS [Total Calls], 
        SUM(CASE WHEN ([LOG].line_result = 1) THEN 1 ELSE 0 END) AS [1 Calls], 
FROM   [DATE RANGE FUNCTION] LEFT JOIN 
         dbo.vCallLog WITH (noexpand) as [LOG] on 0> -1 
WHERE  ([LOG].line_date BETWEEN [Start Date] AND [End Date]) 
GROUP BY [Start Date], [End Date], [Display Start Date], [Display End Date], [LABEL] 

답변

1

것은 내가 제대로 이해 경우

DECLARE @DateRanges TABLE(
     StartDate DATETIME, 
     EndDate DATETIME 
) 

INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 10:00:00','12/02/2010 10:59:59' 
INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 11:00:00','12/02/2010 11:59:59' 
INSERT INTO @DateRanges (StartDate,EndDate) SELECT '12/02/2010 12:00:00','12/02/2010 12:59:59' 

DECLARE @DateValues TABLE(
     DateVal DATETIME 
) 

INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 11:00:00' 
INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 11:01:00' 
INSERT INTO @DateValues (DateVal) SELECT '12/02/2010 12:01:00' 

SELECT t.StartDate, 
     t.EndDate, 
     COUNT(tv.DateVal) CountVal 
FROM @DateRanges t LEFT JOIN 
     @DateValues tv ON tv.DateVal BETWEEN t.StartDate AND t.EndDate 
GROUP BY t.StartDate, 
      t.EndDate 
뭔가를 시도 할 수 있습니다 : 여기
SELECT  [LABEL], [Display Start Date], [Display End Date], 
    SUM(CASE WHEN ([LOG].line_date BETWEEN [Start Date] AND [End Date]) THEN 1 ELSE 0 END) AS [Total Calls], 
    SUM(CASE WHEN ([LOG].line_date BETWEEN [Start Date] AND [End Date]) AND ([LOG].line_result = 1) THEN 1 ELSE 0 END) AS [1 Calls], 

FROM   [DATE RANGE FUNCTION] LEFT JOIN 
         dbo.vCallLog WITH (noexpand) as [LOG] on 0 > -1 
GROUP BY [Start Date], [End Date], [Display Start Date], [Display End Date], [LABEL] 

가 WHERE 솔루션에 대한 몇 가지 SQL입니다 : 여기

케이스 솔루션에 대한 몇 가지 SQL입니다

출력

StartDate    EndDate     CountVal 
----------------------- ----------------------- ----------- 
2010-12-02 10:00:00.000 2010-12-02 10:59:59.000 0 
2010-12-02 11:00:00.000 2010-12-02 11:59:59.000 2 
2010-12-02 12:00:00.000 2010-12-02 12:59:59.000 1 
+0

불행히도, 일치하는 행이없는 범위는 여전히 무시됩니다. –

+0

예제를 실행 해 보았습니다. 테스트 케이스에서 출력을 추가했습니다. –

+0

예가 예상대로 작동하므로 비슷한 개념 테이블 (날짜 범위가있는 날짜, 다른 날짜 목록 ... 본질적으로)이 실패하면 혼란 스럽습니다. 항상 왼쪽 조인에서 예상했던 것을 복제합니다. 실제로 '날짜 행'을 포함하는 색인 ​​된보기가 요인이 될 수 있습니까? –

2

좋아, 조금 pokery하고 내가 내 자신에 대한 약간의 문제를 만든 실현 :

문제가있다 WHERE 절과 COUNT 절에 위치. 만약 내가 동일한 결과 집합에 그때 & 카운트를 사용하고있어, 나는 날짜 사이에 제로 행에 아무것도 얻지 못한다. IF, 그러나, 나는 모든 것을 세고 동일한 결과 집합에서 WHERE를 생략하고 WHERE 절을 JOIN 즉 [x] left join ([b]에서 [a]를 선택하십시오. 여기서 [a]는 @x & @y 사이에 있습니다.) as [c] 나는 모든 행을 반환하고, count는 그 다음 litrally count를 반환합니다.

나는 문제가 WHERE 절 이전이 (컴파일러에 따라)

0

아, 악명 높은 개는을 위해 어떠한 조치가 없기 때문에 카운트가 선택 ommited 생각.당신은 LEFT있을 때 가입하고 오른쪽 열에서 조건을 테스트 절은, 당신이 가진 마십시오 WHERE a는 또한 어디 조건 화합물이있을 때 괄호 대열 OR 문을 넣어하는 것이 좋습니다

WHERE (<Condition based on rightHandTable.Column> OR rightHandTable.Column IS NULL) 

포함 :

WHERE a=1 AND b=1 OR b iS NULL 

이 참으로 평가 될 때 a 및 b = 1 또는 b

null이며

WHERE a=1 AND (b=1 OR b is NULL) 
,745 다르면

이것은 a는 1이어야하고 b는 1 또는 null이어야 함을 의미합니다.

관련 문제