我使用SQL Server 2005.我有一个开始和结束日期。
例如:
START_DATE END_DATE
2011-04-24 2012-05-05
我希望在两个日期之间获得所有开始日(SQL设置为星期日)和每周结束日(星期六)。
期望的结果:
2011-04-24 2011-04-30
2011-05-01 2011-05-07
2011-05-08 2011-05-14
....
2012-04-29 2012-05-05
现在我知道我可以做DATEADD(week, 1, 2011-04-24)
之类的事情,直到我到达我的结束日期,但是直到我到达我的结束日期(没有光标或一段时间)我都不知道该怎么做)。我想在一个查询中完成。
有人可以帮忙吗?
答案 0 :(得分:4)
使用日期功能是一种智能且前瞻性的选择。在sqlteam上有一个很棒的F_TABLE_DATE。
我提取了相关的代码片段,以说明如何将其作为一次性利用:
declare @sDate datetime,
@eDate datetime;
select @sDate = '2011-04-24',
@eDate = '2012-05-05';
;with AllDatesBetween (d)
as (
select dateadd(dd, n-1, @sDate)
from util.Number
where n <= datediff(dd, @sDate, @eDate+1)
)
select distinct
dateadd(dd,(datediff(dd,'17530107',d)/7)*7,'17530107') [weekStart],
dateadd(dd,((datediff(dd,'17530107',d)/7)*7)+6,'17530107') [weekEnd]
from AllDatesBetween
order
by 1,2
答案 1 :(得分:1)
我还将分享一组我使用的常用日期函数。只需将其创建为表值函数:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
CREATE FUNCTION [dbo].[udfCommonDates] (@date datetime)
RETURNS @t table (week_start datetime,
week_end datetime,
lastweek_start datetime,
lastweek_end datetime,
month_start datetime,
month_end datetime,
lastmonth_start datetime,
lastmonth_end datetime,
yesterday_start datetime,
yesterday_end datetime,
today_start datetime,
today_end datetime,
thisweek_monday_start datetime,
thisweek_monday_end datetime,
year_start datetime,
year_end datetime,
tomorrow_noon datetime,
today_noon datetime,
date_only datetime)
BEGIN
INSERT @t
SELECT
dbo.get_week_start ( @date ) AS week_start,
dbo.get_week_end ( @date ) AS week_end,
dbo.get_week_start ( DATEADD(d, -7, @date ) ) AS lastweek_start,
dbo.get_week_end ( DATEADD(d, -7, @date ) ) AS lastweek_end,
dbo.get_month_start( @date ) AS month_start,
dbo.get_month_end ( @date ) AS month_end,
dbo.get_month_start ( DATEADD(m,-1, @date) ) AS lastmonth_start,
dbo.get_month_end ( DATEADD(m,-1,@date) ) AS lastmonth_end,
dbo.get_yesterday_start ( @date ) AS yesterday_start,
dbo.get_yesterday_end ( @date ) AS yesterday_end,
dbo.get_today_start (@date) AS today_start,
dbo.get_today_end ( @date ) AS today_end,
dbo.get_weekday_start(1,@date) AS thisweek_monday_start,
dbo.get_weekday_end(1,@date) AS thisweek_monday_end,
dbo.get_year_start(@date) AS year_start,
dbo.get_year_end(@date) AS year_end,
dbo.get_tomorrow_noon(@date) AS TomorrowNoon,
dbo.get_today_noon(@date) AS TodayNoon,
dbo.get_date_only(@date) AS DateOnly
RETURN
END
以下是这些的标量值函数:
CREATE FUNCTION [dbo].[get_date_only] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(day, DateDiff(day, 0, GetDate()), 0)
END
GO
CREATE FUNCTION [dbo].[get_month_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(ms, -3, dateadd (m,datediff(m,0,
dateadd(m,1,@date)),0))
END
GO
CREATE FUNCTION [dbo].[get_month_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(m,datediff(m,0, @date),0)
END
GO
CREATE FUNCTION [dbo].[get_today_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
return dateadd(ms, -3, datediff(d,0,dateadd(d,1,@today)))
END
GO
CREATE FUNCTION [dbo].[get_today_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,0, @date),0))
END
GO
CREATE FUNCTION [dbo].[get_today_start] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(day, 0, datediff(d,0,@today))
END
GO
CREATE FUNCTION [dbo].[get_tomorrow_noon](@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,-1, @date),0))
END
GO
CREATE FUNCTION [dbo].[get_week_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,7-datepart(weekday, @date),@date))-1900, 0)
+ dateadd(ms, -3,
dateadd(dy, datepart(dy,
dateadd(weekday,7-datepart(weekday, @date),@date)),0) )
END
GO
CREATE FUNCTION [dbo].[get_week_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,1-datepart(weekday, @date),@date))-1900, 0)
+ dateadd(dy, datepart(dy,
dateadd(weekday,1-datepart(weekday, @date),@date))-1,0)
END
GO
CREATE FUNCTION [dbo].[get_weekday_end] (@weekday tinyint,
@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,@weekday-
datepart(weekday, @date),@date))-1900, 0)
+ dateadd(ms, -3,
dateadd(dy, datepart(dy,
dateadd(weekday,@weekday-datepart(weekday, @date),
@date)),0) )
END
GO
CREATE FUNCTION [dbo].[get_weekday_start] (@weekday tinyint,
@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,@weekday-
datepart(weekday, @date),@date))-1900, 0)
+ dateadd(dy, datepart(dy,
dateadd(weekday,@weekday-datepart(weekday, @date),
@date))-1,0)
END
GO
CREATE FUNCTION [dbo].[get_year_end] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(year, DATEDIFF(year, 0, GetDate())+1, 0)-1
END
GO
CREATE FUNCTION [dbo].[get_year_start] (@date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(year,DATEDIFF(year,0, @date),0)
END
GO
CREATE FUNCTION [dbo].[get_yesterday_end] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(ms, -3, datediff(d,0,@today))
END
GO
CREATE FUNCTION [dbo].[get_yesterday_start] (@today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN dateadd(day, -1, datediff(d,0,@today))
END
GO
你可以像这样执行整个表值函数:
SELECT * FROM [MyDB].[dbo].[udfCommonDates] (GetDate())
答案 2 :(得分:0)
刚刚找到了一种方法来实现递归!
;WITH DaysOfWeek AS
(
SELECT {d '2011-04-24'} AS StartOfWeek
UNION ALL
SELECT DATEADD( week, 1, jdr.StartOfWeek) AS StartOfWeek
FROM JoursDuReleve jdr
WHERE DATEADD(week, 1, jdr.StartOfWeek) <= {d '2012-05-05'}
)
SELECT StartOfWeek, DATEADD(day, 6, StartOfWeek) AS EndOfWeek
FROM DaysOfWeek
ORDER BY StartOfWeek DESC
OPTION (MAXRECURSION 0)