【发布时间】:2017-02-23 06:17:35
【问题描述】:
我想根据给定的开始日期获取自定义的堡垒之夜时段。 我有一个看起来像这样的表:
IF OBJECT_ID('tempdb..#tbl1') IS NOT NULL DROP TABLE #tbl1
SET DATEFIRST 1
DECLARE @StartDateTime DATETIME
DECLARE @EndDateTime DATETIME
SET @StartDateTime = '2016-09-03'
SET @EndDateTime = '2017-01-28';
WITH DateRange(DateData) AS
(
SELECT @StartDateTime as Date
UNION ALL
SELECT DATEADD(d,1,DateData)
FROM DateRange
WHERE DateData < @EndDateTime
)
SELECT ROW_NUMBER() OVER(ORDER BY DateData ASC) As ROWNum,DateData AS Date1
into #tbl1
FROM DateRange
OPTION (MAXRECURSION 0)
GO
SELECT top 10 * FROM #tbl1
Date1
2016-09-09 00:00:00.000
2016-09-10 00:00:00.000
2016-09-11 00:00:00.000
2016-09-12 00:00:00.000
2016-09-13 00:00:00.000
2016-09-14 00:00:00.000
2016-09-15 00:00:00.000
2016-09-16 00:00:00.000
2016-09-17 00:00:00.000
2016-09-18 00:00:00.000
2016-09-19 00:00:00.000
2016-09-20 00:00:00.000
2016-09-21 00:00:00.000
2016-09-22 00:00:00.000
我想说我双周周期的第一个日期是 2016 年 9 月 9 日,它结束于 2016 年 9 月 22 日。我如何获得每个日期的双周结束日期。
所以我希望它看起来像
Date1 FortNightEndDate
2016-09-09 00:00:00.000 2016-09-22 00:00:00.000
2016-09-10 00:00:00.000 2016-09-22 00:00:00.000
2016-09-11 00:00:00.000 2016-09-22 00:00:00.000
2016-09-12 00:00:00.000 2016-09-22 00:00:00.000
2016-09-13 00:00:00.000 2016-09-22 00:00:00.000
2016-09-14 00:00:00.000 2016-09-22 00:00:00.000
2016-09-15 00:00:00.000 2016-09-22 00:00:00.000
2016-09-16 00:00:00.000 2016-09-22 00:00:00.000
2016-09-17 00:00:00.000 2016-09-22 00:00:00.000
2016-09-18 00:00:00.000 2016-09-22 00:00:00.000
2016-09-19 00:00:00.000 2016-09-22 00:00:00.000
2016-09-20 00:00:00.000 2016-09-22 00:00:00.000
2016-09-21 00:00:00.000 2016-09-22 00:00:00.000
2016-09-22 00:00:00.000 2016-09-22 00:00:00.000
我使用的是 SQL Server 2005。
回答: 我能够使用以下代码解决它。基本上我只是创建了 3 个表: 开始日期 结束日期 中间日期
Start/EndDates 表只有我 2 周期间的开始和结束以及 ID(行号) InbetweenDates 表包含两个日期之间的所有日期,并且还有一个 ID 列,但不是每行增加 1 个,而是每 14 行增加 1 个。 然后我就加入了 3 张桌子。本质上,Start/EndDates 表是查找表。 我从here 获得了每 14 天代码的 RowNumber。
-- BEtween Dates
IF OBJECT_ID('tempdb..#BetweenDates') IS NOT NULL DROP TABLE #BetweenDates
DECLARE @StartDateTime DATETIME
DECLARE @EndDateTime DATETIME
SET @StartDateTime = '2016-09-09'
SET @EndDateTime = '2017-04-30';
WITH DateRange(DateData) AS
(
SELECT @StartDateTime as Date
UNION ALL
SELECT DATEADD(d,1,DateData)
FROM DateRange
WHERE DateData < @EndDateTime
)
SELECT
DateData
into #BetweenDates
FROM DateRange
OPTION (MAXRECURSION 0)
GO
select
(case when convert(int, (ROW_NUMBER() OVER (Order by (select 0)) % 14))=0 then 0 else 1 end)
+ convert(int, (ROW_NUMBER() OVER (Order by (select 0)) / 14)) as ID
,DateData
INTO #BetweenDates_ID
from #BetweenDates
-- Start Dates
IF OBJECT_ID('tempdb..#StartDates') IS NOT NULL DROP TABLE #StartDates
DECLARE @StartDateTime DATETIME
DECLARE @EndDateTime DATETIME
SET @StartDateTime = '2016-09-09'
SET @EndDateTime = '2017-04-30';
WITH DateRange(DateData) AS
(
SELECT @StartDateTime as Date
UNION ALL
SELECT DATEADD(d,14,DateData)
FROM DateRange
WHERE DateData < @EndDateTime
)
SELECT ROW_NUMBER() OVER(ORDER BY DateData ASC) As ID,DateData
into #StartDates
FROM DateRange
OPTION (MAXRECURSION 0)
GO
-- End Dates
IF OBJECT_ID('tempdb..#EndDates') IS NOT NULL DROP TABLE #EndDates
DECLARE @StartDateTime DATETIME
DECLARE @EndDateTime DATETIME
SET @StartDateTime = '2016-09-22'
SET @EndDateTime = '2017-04-30';
WITH DateRange(DateData) AS
(
SELECT @StartDateTime as Date
UNION ALL
SELECT DATEADD(d,14,DateData)
FROM DateRange
WHERE DateData < @EndDateTime
)
SELECT ROW_NUMBER() OVER(ORDER BY DateData ASC) As ID,DateData
into #EndDates
FROM DateRange
OPTION (MAXRECURSION 0)
GO
--SELECT * FROM #StartDates
--SELECT * FROM #EndDates
--SELECT * FROM #BetweenDates_ID
SELECT
st.DateData AS StartDate
,ed.DateData AS EndDate
,bd.DateData AS BetweenDate
FROM
#StartDates st
JOIN
#EndDates ed
ON st.ID = ed.ID
LEFT JOIN
#BetweenDates_ID bd
ON st.ID = bd.ID
【问题讨论】:
-
什么是双周结束日期?你是怎么计算的?
-
基本上我需要从周三到周四(2 周)的两周结束日期。在示例中,从 2016-09-09 到 2016-09-22 的所有日期都属于两周结束日期 2016-09-22
标签: sql function tsql date datetime