我有下面的sql查询,它选择截至3个月前的日期。如何更改它以选择三个月前的最后工作日?
(SELECT DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())-3,0)))
答案 0 :(得分:0)
对于MSSQL。
如果是"最后一个工作日"你只是指周六和周日,你可以尝试以下查询
在MSSQL中,每周的天数取决于@@ datefirst的值(您可以使用SET DATEFIRST n设置它,其中n = 1,...,7)。
例如。如果@@ datefirst = 7周的第一天是星期日,那么DATEPART(dw,GETDATE())将返回1,今天是星期日。
此查询会尝试为您提供最后一个工作日"除了@@ datefirst值。
SELECT DATEADD(d, - CASE WHEN DATEPART(dw,SP)+@@datefirst IN (7,8) THEN DATEPART(dw,SP) + @@datefirst-6 ELSE 0 END,SP) AS ND
FROM (
SELECT DATEADD(d,-1,DATEADD(mm,
DATEDIFF(m,0,GETDATE())
-3,0)) AS SP ) A
输出
2017-04-28 00:00:00.000
答案 1 :(得分:0)
以下是需要考虑的事项:2010年5月31日星期一恰好是Federal Holiday in the United States。因此,对于许多企业(或业务部门)而言,该月的最后一个工作日实际上是2010年5月28日星期五。
所以,这是一个可以解释假期的强大解决方案。
首先我们假设我们有一个Calendar Table。
对于Calendar
表,Holiday
表可以定义为:
create table Holiday (id int primary key foreign key references Calendar)
并填充如此(示例以美国为中心,但可以推广到任何国家/地区):
insert Holiday
--Labor Day
select C.* from Calendar C where C.month = 5 and C.day_name = 'monday' and C.day_of_month > 25 union
--Christmas
select C.* from Calendar C where C.month = 12 and C.day_of_month = 25 union
--Thanksgiving
select C.* from Calendar C where C.month = 11 and c.day_name = 'thursday' and abs(C.day_of_month - 25) <= 3
--etc...
因此,对于典型的业务,WorkDay
视图可能被定义为:
create view WorkDay as
select id from Calendar where day_name not in ('saturday', 'sunday')
except select id from Holiday
因此,我们的最终查询只是:
with Q as (select top 1 * from Calendar C where datediff(month, C.date, getdate()) = 3),
P as
(
select C.* from Calendar C
cross apply ( select * from Q where C.year = Q.year and C.month = Q.month) L
)
select top 1 * from P inner join WorkDay W on W.id = P.id order by P.id desc
问获取三个月前的任何月份发生的日期。
P 获取 Q 返回的同一个月中发生的所有日期。
最后,最后一个查询返回 P 返回的月份的最后一天,即工作日,其中&#34;工作日&#34;意味着不是星期六或星期日而不是假期。
在此示例中,Calendar表定义为:
create table Calendar
(
id int primary key identity,
date datetime unique not null,
day_of_week as datepart(dw, date),
month as datepart(month, date),
day_name as datename(dw, date),
year as datepart(year, date),
day_of_month as datepart(day, date),
week as datepart(week, date)
)