使用 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
我希望在单个结果中获得 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