在sql server 2005中查找月份的第n天

时间:2014-10-08 07:29:38

标签: sql sql-server sql-server-2005

我想在sql server 2005中找到给定月份的第n天(例如: - 第一个星期日,第二个星期二,上周五等)。我曾经使用过

DATEADD(WEEK, DATEDIFF(WEEK, 0,
DATEADD(DAY, 6 - DATEPART(DAY, GETDATE()), GETDATE())), 6)  

它将在一个月的第一个星期日返回,但不知道如何根据用户的要求找到我需要在第n天返回的第n天

请帮助找到这个

任何帮助或建议都会感激不尽

谢谢和问候

2 个答案:

答案 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/