我想在sql server 2005中找到给定月份的第n天(例如: - 第一个星期日,第二个星期二,上周五等)。我曾经使用过
DATEADD(WEEK, DATEDIFF(WEEK, 0,
DATEADD(DAY, 6 - DATEPART(DAY, GETDATE()), GETDATE())), 6)
它将在一个月的第一个星期日返回,但不知道如何根据用户的要求找到我需要在第n天返回的第n天
请帮助找到这个
任何帮助或建议都会感激不尽
谢谢和问候
答案 0 :(得分:0)
许多数据仓库都有日期维度。日期和星期几等内容包含在此表中。它可以被索引并具有相对较好的速度,因为100年x一年365天的数据并不多。
下面我使用一个计数表来为今年创建一个公用表表达式。我在2014年11月创建另一个。从那里,我使用窗口函数按顺序排列星期几的顺序。
如果确实拥有日期维度中的所有数据,您甚至可以将出现次数放在该月的表格中。
以下示例将拉动2014年11月的第三个星期五。
--
-- Why not use a date dimension if you need this functionality often?
--
;
with
cte_Tally
as
(
SELECT ROW_NUMBER() over (order by (select 1)) as rn
FROM master.sys.all_columns c
),
cte_Year
as
(
select
rn as my_doy_num,
dateadd(d, rn, '20140101') as my_day_dte,
month(dateadd(d, rn, '20140101')) as my_month_num,
case month(dateadd(d, rn, '20140101'))
when 1 then 'jan'
when 2 then 'feb'
when 3 then 'mar'
when 4 then 'apr'
when 5 then 'may'
when 6 then 'jun'
when 7 then 'jul'
when 8 then 'aug'
when 9 then 'sep'
when 10 then 'oct'
when 11 then 'nov'
when 12 then 'dec'
else ''
end as my_month_desc,
datepart(dw, dateadd(d, rn, '20140101')) as my_dow_num,
case datepart(dw, dateadd(d, rn, '20140101'))
when 1 then 'sun'
when 2 then 'mon'
when 3 then 'tue'
when 4 then 'wed'
when 5 then 'thu'
when 6 then 'fri'
when 7 then 'sat'
else ''
end as my_dow_desc
from cte_Tally
where rn < 365
),
cte_Nov_2014
as
(
select
my_day_dte,
my_month_desc,
my_dow_desc,
ROW_NUMBER() over (partition by my_dow_desc order by my_day_dte, my_dow_desc) as my_occurence
from cte_Year
where my_month_num = 11
--order by my_dow_desc
)
select *
from cte_Nov_2014
where my_dow_desc = 'fri' and my_occurence = 3
答案 1 :(得分:-1)
-- 1 find the first nth weekday (Mon/Tue/Wed/Thu/Fri/Sat/Sun) of the month where @dt is in
-- for example, find the 5th Friday of the month of Aug, 2013
declare @nth int=5, @dt datetime='2013-08-12';
declare @dw tinyint =5 -- 1=Mon,2= Tue,3=Wed, 4=Thur, 5=Fri, 6=Sat, 7=Sun
select [1st_nth_wkday]=case when datepart(dw, dateadd(month,
datediff(month,0,@dt),0)+@@datefirst-1) >= @dw
then dateadd(day, (@nth-1)*7 + (7-(datepart(dw, dateadd(month,
datediff(month,0,@dt),0)+@@datefirst-1)-@dw)), dateadd(month,
datediff(month,0,@dt),0))
else dateadd(day, (@nth-1)*7 + (0-(datepart(dw, dateadd(month,
datediff(month,0,@dt),0)+@@datefirst-1)-@dw)), dateadd(month,
datediff(month,0,@dt),0))
end
go
-- 2 find the last nth weekday (Mon/Tue/Wed/Thu/Fri/Sat/Sun) of the month
where @dt is in
-- find the 2nd last Sunday of current month
declare @nth int=2, @dt datetime=current_timestamp;
declare @dw tinyint =7 -- 1=Mon,2= Tue,3=Wed, 4=Thur, 5=Fri, 6=Sat, 7=Sun
select [last_nth_wkday]=case when datepart(dw, dateadd(month,
datediff(month,0,@dt)+1,0)-1+@@datefirst-1) >= @dw
then dateadd(day, -(@nth-1)*7 - (datepart(dw, dateadd(month,
datediff(month,0,@dt)+1,0)-1+@@datefirst-1)-@dw), dateadd(month,
datediff(month,0,@dt)+1,0)-1)
else dateadd(day, -(@nth)*7 - (datepart(dw, dateadd(month,
datediff(month,0,@dt)+1,0)-1+@@datefirst-1)-@dw), dateadd(monI th,
datediff(month,0,@dt)+1,0)-1)
end
go
我实际上是在这里写博客:http://www.sqlservercentral.com/blogs/jeffrey_yao/2014/03/02/fun-in-datetime-calculations/