2011-12-07 5 views
0

다음 스크립트는 다른 특정 시간 간격을 뺀 후 남은 시간 간격을 계산합니다.다른 시간 간격을 뺀 후 남은 시간 간격 (시작 날짜 -> 종료 날짜) 계산

결국 간격이 채워진 채로 남았습니다.

내가 작성한 스크립트는 다음과 같습니다. 누구든지이 일을하는 더 좋은 방법을 알고 있습니까?

 SELECT * FROM SuspensionPeriod susPer WHERE id_document = 564148 

DECLARE @idDocument BIGINT, @docBeginDate DATETIME, @docEndDate DATETIME 

SET @idDocument = 564148 

SELECT @docBeginDate = start_date, @docEndDate = end_date FROM Document md WHERE md.id_document = @idDocument 

SELECT RowNum = Row_number() OVER(ORDER BY suspended_from), * 
INTO #SuspensionPeriods 
FROM SuspensionPeriod susPer WHERE susPer.id_document = @idDocument 

DECLARE @MaxRownum INT 

SET @MaxRownum = (SELECT Max(RowNum) FROM #SuspensionPeriods) 

DECLARE @Iter INT 

SET @Iter = (SELECT Min(RowNum) FROM #SuspensionPeriods) 

DECLARE @intervalBegin DATETIME, @intervalEnd DATETIME 

WHILE @Iter <= @MaxRownum 
    BEGIN 

     IF @Iter = 1 
     BEGIN 
      SET @intervalBegin = @docBeginDate 
      SELECT @intervalEnd = suspended_from FROM #SuspensionPeriods WHERE RowNum = @Iter 

      print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      print '=============================' 


      --SELECT @intervalBegin = suspended_until FROM #SuspensionPeriods WHERE RowNum = @Iter 
      --SELECT @intervalEnd = suspended_from FROM #SuspensionPeriods WHERE RowNum = @Iter + 1 

      --print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      --print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      --print '=============================' 
     END 

     IF @Iter <> 1 AND @Iter <> @MaxRownum 
     BEGIN 
      SELECT @intervalBegin = suspended_until FROM #SuspensionPeriods WHERE RowNum = @Iter - 1 
      SELECT @intervalEnd = suspended_from FROM #SuspensionPeriods WHERE RowNum = @Iter 

      print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      print '=============================' 


      SELECT @intervalBegin = suspended_until FROM #SuspensionPeriods WHERE RowNum = @Iter 
      SELECT @intervalEnd = suspended_from FROM #SuspensionPeriods WHERE RowNum = @Iter + 1 

      print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      print '=============================' 
     END 

     IF @Iter = @MaxRownum 
     BEGIN 
      --SELECT @intervalBegin = suspended_until FROM #SuspensionPeriods WHERE RowNum = @Iter - 1 
      --SELECT @intervalEnd = suspended_from FROM #SuspensionPeriods WHERE RowNum = @Iter 

      --print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      --print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      --print '=============================' 

      SELECT @intervalBegin = suspended_until FROM #SuspensionPeriods WHERE RowNum = @Iter 
      SELECT @intervalEnd = @docEndDate 

      print dbo.fnFormatDate(@intervalBegin,'yyyy.MM.dd') 
      print dbo.fnFormatDate(@intervalEnd,'yyyy.MM.dd') 
      print '=============================' 
     END 
     -- run your operation here 
     SET @Iter = @Iter + 1 
    END 

DROP TABLE #SuspensionPeriods 
+0

"더 나은"무엇을 의미합니까? 이미 가지고있는 스크립트의 문제점은 무엇입니까? 잘못된 결과가 나온다면 몇 가지 샘플 데이터를 보여주고 문제를 보여주기 위해 스크립트를 최소한으로 줄여야합니다. 위의 PRINT 및 주석은 관련이 없습니다. – Pondlife

+1

짧은 대답 = 예. 매우 선형적인 프로그래밍 (행 번호를 추가하여 증가 된 while 루프는 SQL 로직이 좋지 않은 경우 한 번에 모든 행을 수행하고자 함)을 수행하고 아마도 세트 기반, 아마도 하나의 명령문으로 전환 될 수 있습니다. 우리는 당신에게 어떤 테이블 스키마와 더 나은 아이디어를 제공 할 필요가있을 것입니다. 여기에 예제를 쓸 충분한 정보가 없습니다. – Twelfth

답변

0

방법에 대한

SELECT MIN(md.start_date), MIN(sp.suspended_from) 
    FROM Document md 
    JOIN SuspensionPeriod sp ON sp.id_document = md.id_document 
    WHERE md.id_document = @idDocument 
UNION 
SELECT sp.suspended_to, (SELECT COALESCE(MIN(spnext.suspended_from), md.end_date) FROM SuspensionPeriod spnext WHERE sp.id_document=spnext.id_document AND spnext.suspended_from > sp.suspended_to) 
    FROM Document md 
    JOIN SuspensionPeriod sp ON sp.id_document = md.id_document 
    WHERE md.id_document = @idDocument 
관련 문제