2010-08-13 3 views
1

다음 날짜와 시간 범위에서 각 날짜의 시즌을 가져온 다음 각 시즌을 시작 및 종료 날짜와 밤 수로 그룹화하는 다음 SQL을 사용합니다. 그게 중요하지 않지만 내 질문은 어느 쪽이 좋았는지, 아래에서 해본 방법 또는 @dateSeasons가 두 번째 쿼리에서 사용될 때마다 하위 쿼리로 첫 번째 select 문을 사용하는 것입니다. 두 방법 모두 똑같이 실행되는 것처럼 보이지만이 방법은 더 깔끔하게 보입니다. 깔끔한 찾고SQL 2008의 임시 테이블 또는 하위 쿼리에 여러 조인

DECLARE @dateSeasons TABLE ([date] date, seasonID int) 

INSERT INTO @dateSeasons 
SELECT D.[date], S.ID 
FROM @dates AS D 
CROSS APPLY (

    SELECT TOP 1 ID 
    FROM dbo.Seasons 
    WHERE bookingID = @bookingID 
    AND D.[date] BETWEEN startDate AND endDate 
    ORDER BY ID DESC 

) AS S 


SELECT MIN([date]), endDate, DATEDIFF(DAY, MIN([date]), DATEADD(DAY, 1, endDate)), seasonID 
FROM (

    SELECT S1.seasonID, S1.[date], (

     SELECT MAX([date]) 
     FROM @dateSeasons S2 
     WHERE S2.seasonID = S1.seasonID 
     AND NOT EXISTS (

      SELECT NULL 
      FROM @dateSeasons S3 
      WHERE S3.[date] < S2.[date] 
      AND S3.[date] > S1.[date] 
      AND S3.seasonID <> S1.seasonID 

     ) 

    ) AS endDate 
    FROM @dateSeasons S1 
) AS results 
GROUP BY endDate, seasonID 
ORDER BY MIN([date]) 
+1

"그것이 무엇을하는 것은 중요하지 않다"- 당신거야이 생각! 종종 사람들은 해결하려는 실제 문제가 아니라 문제에 대한 인식 된 해결책을 알려줄 것입니다. –

+0

분명히 나에게 중요하지만, 내가 묻고있는 질문에는 중요하지 않다. – markvpc

+1

더 나은 것은 특정 RDBMS, 테이블 구조, 색인 및 데이터의 크기 분포에 크게 의존하게 될 것입니다. 귀하의 질문에 이들 중 어느 것도 명시되어 있지 않습니다. 두 개의 쿼리 중 더 나은 쿼리를 결정하는 가장 좋은 방법은 RDBMS에서 사용할 수있는 쿼리 통계 및 쿼리 계획을 보면서 서로를 테스트하는 것입니다. Mitch의 의견과 답변에 관해서는 "더 이상 없습니다"라는 답변이 더 좋기 때문에 대개 중요합니다. –

답변

0

는 SQL 코드를 서면으로 무관입니다. 우아하게 보이면 종종 성능 측면에서이 문제를 해결할 수있는 가장 좋은 방법이 입니다 ().

가장 확실한 방법은 테스트하는 두 가지 방법이 동일한 결과를 반환하는지 확인한 다음 성능 테스트를 수행하고 실행 계획을 확인하는 것입니다 (또는 mySQL에서 설명하십시오). 쿼리를 더 잘 만드는 기술은 데이터베이스와도 관련이 있습니다. SQL Server의 성능 튜닝에 가장 적합한 것은 오라클에서 최악의 가능성 일 수 있습니다.

0

때때로 당신은 common table expression (CTE)를 사용하여 더 나은 성능을 얻을 수 있습니다 :

WITH 
dateSeasons ([date], [seasonID]) 
AS 
(
    SELECT D.[date], S.ID 
    FROM @dates AS D 
    CROSS APPLY (

     SELECT TOP 1 ID 
     FROM dbo.Seasons 
     WHERE bookingID = @bookingID 
     AND D.[date] BETWEEN startDate AND endDate 
     ORDER BY ID DESC 

    ) AS S 
) 

SELECT MIN([date]), endDate, DATEDIFF(DAY, MIN([date]), DATEADD(DAY, 1, endDate)), seasonID 
FROM (

    SELECT S1.seasonID, S1.[date], (

     SELECT MAX([date]) 
     FROM dateSeasons S2 
     WHERE S2.seasonID = S1.seasonID 
     AND NOT EXISTS (

      SELECT NULL 
      FROM dateSeasons S3 
      WHERE S3.[date] < S2.[date] 
      AND S3.[date] > S1.[date] 
      AND S3.seasonID <> S1.seasonID 

     ) 

    ) AS endDate 
    FROM dateSeasons S1 
) AS results 
GROUP BY endDate, seasonID 
ORDER BY MIN([date])