我正在重新访问我为报表编写的一些旧代码,当时我对SQL(MSSQL)还很陌生。它做它应该做的,但它不是最漂亮或最有效的。我怎样才能重写这个select语句使用组而不是使用循环
下面的虚拟代码模仿了我现在所拥有的东西。在这里,我试图计算过去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
我花了一点时间回到这里,但是这个解决方案对我来说效果很好,并且提供了比我原来的解决方案更高的性能。 – Curtis 2012-07-27 18:16:00