【问题标题】:Recursive Start of Week Query with SUM使用 SUM 进行递归周初查询
【发布时间】:2020-04-08 22:52:10
【问题描述】:

我希望在单个结果中获得 n 周的每周工作时数总和。我遇到了这个小宝石,它将使用递归查询提供从当天开始返回 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 查询?

【问题讨论】:

    标签: sql-server datetime recursion common-table-expression


    【解决方案1】:

    坚持是有回报的,但我不得不跳出我被困的那个盒子,使用一个临时表和一个 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
    

    【讨论】:

      猜你喜欢
      • 2020-11-06
      • 2019-01-23
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      相关资源
      最近更新 更多