Рекурсивный запрос начала недели с помощью SUM - PullRequest
0 голосов
/ 09 апреля 2020

Я хочу получить сумму отработанных часов в неделю за 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

enter image description here

Это суммы общее количество часов во всем диапазоне дат в соответствии с рекурсивной частью запроса. Мне нужно найти способ фильтрации часов в этой рекурсивной части на основе 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?

1 Ответ

0 голосов
/ 09 апреля 2020

Постоянство окупается, но мне пришлось go из той коробки, в которой я застрял, и использовать временную таблицу и WHILE l oop.

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

enter image description here

...