2011-12-07 25 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ロジックが貧弱なため、一度にすべての行を実行したい)、おそらくセットベース、おそらくは1つのステートメントに切り替えることができます。テーブルスキーマと、達成しようとしていることのより良いアイデアを提供する必要があります。ここに例を書くのに十分な情報がありません。 – 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 
関連する問題