使用 SUM 的递归周开始查询

Recursive Start of Week Query with SUM

我希望在单个结果中获得 n 周的每周工作小时数总和。我遇到了这个小 gem,它将使用递归查询提供从当天开始的 n 周的周列表。

DECLARE @dt DATE = '1900-01-01';
declare @startDate datetime , @endDate datetime
set @startDate = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP)-10, @dt)
set @endDate = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP)-1, @dt)

;with T(startday) as
(
    select @startDate as startday
        union all
    select startday + 7
        from T
        where startday < @endDate
)
select startday as [StartDate], DATEADD(DD, 7, startday) AS [EndDate] from T

如果我可以使用类似的递归查询,那就太好了。否则,我可以构建一个包含每个日期范围的并集的大查询。我在这上面花的时间比我愿意承认的要多。

如果我试试。

DECLARE @monDT DATE = '1900-01-01';
DECLARE @startDate DATETIME , @endDate DATETIME
SET @startDate = DATEADD(WEEK, DATEDIFF(WEEK, @monDT, CURRENT_TIMESTAMP)-10, @monDT)
SET @endDate = DATEADD(WEEK, DATEDIFF(WEEK, @monDT, CURRENT_TIMESTAMP), @monDT)

;WITH T(startDay, endDay, StartDateTime, FinishedDateTime, ActualDurationHours)
AS (
    SELECT
        @startDate AS startDay,
        @endDate AS endDay,
        [WorkOrderTrade].[StartDateTime],
        [WorkOrderTrade].[FinishedDateTime],
        [WorkOrderTrade].[ActualDurationHours]
        FROM [WorkOrderTrade]
        WHERE [WorkOrderTrade].[TradeContactID] = 783
        AND [WorkOrderTrade].[StartDateTime] > @startDate
        AND [WorkOrderTrade].[FinishedDateTime] < @endDate
    UNION ALL
    SELECT
        startDay + 7,
        endDay,
        StartDateTime,
        FinishedDateTime,
        ActualDurationHours
        FROM T
        WHERE startDay < @endDate
)
SELECT TOP (100) 
    startDay,
    DATEADD(DD, 7, startday) AS endDay,
    SUM(ActualDurationHours)
    FROM T
    GROUP BY startDay, endDay

它根据查询的递归部分对整个日期范围内的总小时数求和。我需要想出一种方法,根据每周的 startDay 和 endDay 过滤该递归部分中的小时数。像下面这样的东西会很好但是你不能在递归部分累加。

SELECT
        startDay + 7,
        StartDateTime,
        FinishedDateTime,
        (SELECT SUM(ActualDurationHours) FROM [WorkOrderTrade] WHERE [WorkOrderTrade].[TradeContactID] = 783 AND (StartDateTime > startDay AND FinishedDateTime < DATEADD(DD, 7, startDay)))
        FROM T
        WHERE startDay < @endDate

有没有办法或者我是否需要构建一个大型 UNION 查询?

坚持不懈是有回报的,但我不得不跳出我陷入困境的那个盒子,使用一个临时的 table 和一个 WHILE 循环。

DECLARE @monDT DATE = '1900-01-01';
DECLARE @startDate DATETIME , @endDate DATETIME, @startOfWeek DATETIME
SET @startDate = DATEADD(WEEK, DATEDIFF(WEEK, @monDT, CURRENT_TIMESTAMP)-10, @monDT)
SET @endDate = DATEADD(WEEK, DATEDIFF(WEEK, @monDT, CURRENT_TIMESTAMP)+1, @monDT)
SET @startOfWeek = @startDate

CREATE TABLE #tmpDuration (
    StartDate DATETIME,
    EndDate DATETIME,
    LoggedHours NUMERIC(18,7)
)

WHILE @startOfWeek < @endDate
BEGIN
    INSERT INTO #tmpDuration
    SELECT
    @startOfWeek,
    DATEADD(DD, 7, @startOfWeek),
    SUM([WorkOrderTrade].[ActualDurationHours])
        FROM [WorkOrderTrade]
        WHERE [WorkOrderTrade].[TradeContactID] = 783
            AND [WorkOrderTrade].[StartDateTime] > @startOfWeek
            AND [WorkOrderTrade].[StartDateTime] < DATEADD(DD, 7, @startOfWeek)

    SET @startOfWeek = DATEADD(DD, 7, @startOfWeek)
END

SELECT * FROM #tmpDuration

DROP TABLE #tmpDuration