SQL (MSSQL) にまだ慣れていないときにレポート用に書いた古いコードを再検討しています。それは想定されていることを行いますが、最もきれいでも最も効率的でもありません。
以下のダミーコードは、私が現在持っているものを模倣しています。ここでは、過去 5 週間に開かれた契約の数を取得しようとしています。この例では、契約の開始日が特定の週の前または中、終了日が特定の週の最中または後に発生する場合、契約はオープンであると見なされます。
dbo.GetWeekStart(@Date DATETIME, @NumOfWeeks INT, @FirstDayOfWeek CHAR(3)) は、指定された週数の日付に基づいて各週の最初の日を返す関数です。つまり、SELECT * FROM dbo.GetWeekStart('20120719', -2, 'MON') は、2012 年 7 月 19 日より前の 2 つの月曜日を返します。
これをどのように単純化できますか?ループなしでこれを行う人がいると思いますが、私はそれを理解できていません。
DECLARE @RunDate DATETIME,
@Index INT,
@RowCount INT,
@WeekStart DATETIME,
@WeekEnd DATETIME
DECLARE @Weeks TABLE
(
WeekNum INT IDENTITY(0,1),
WeekStart DATETIME,
WeekEnd DATETIME
)
DECLARE @Output TABLE
(
WeekStart DATETIME,
OpenContractCount INT
)
SET @RunDate = GETDATE()
INSERT INTO @Weeks (WeekStart, WeekEnd)
SELECT WeekStart,
DATEADD(ss,-1,DATEADD(ww,1,WeekStart))
FROM dbo.[GetWeekStart](@RunDate, -5, 'MON')
SET @RowCount = (SELECT COUNT(*) FROM @Weeks)
SET @Index = 0
WHILE @Index < @RowCount
BEGIN
SET @WeekStart = (SELECT WeekStart FROM @Weeks WHERE WeekNum = @Idx)
SET @WeekEnd = (SELECT WeekEnd FROM @Weeks WHERE WeekNum = @Idx)
INSERT INTO @Output (WeekStart, OpenContractCount)
SELECT @WeekStart,
COUNT(*)
FROM Contracts c
WHERE c.StartDate <= @WeekEnd
AND ISNULL(c.EndDate, GETDATE()) >= @WeekStart
SET @Index = @Index + 1
END
SELECT * FROM @Output