传递周日名称以获取SQL中最近的日期

web*_*ad3 5 sql-server date

我正在处理一个处理频率值的查询(即星期一,星期二等等 - 思考作业).

所以在我的查询中,我目前有一个结果

jobId:1, personId:100, frequencyVal: 'Mondays'
jobId:2, personId:101, frequencyVal: 'Saturdays'
Run Code Online (Sandbox Code Playgroud)

我需要的是frequencyVal的下一个4个未来(或当前)日期.

所以如果今天是2015年1月3日

我需要我的结果集

jobId:1, personId:100, frequencyVal: 'Mondays', futureDates: '1/5,1/12,1/19,1/26'
jobId:2, personId:102, frequencyVal: 'Saturdays', futureDates: '1/3,1/10,1/17,1/24'
Run Code Online (Sandbox Code Playgroud)

我正在查看以下帖子: 如何查找给定日期的最近(星期几)

但这是针对特定日期的.我正在看这是一个Web应用程序,我想要当前日期的日期.因此,如果我尝试在下周二运行此查询,则将来的日期为jobId:1 would remove the 1/5 and add the 2/2.

有没有办法传递工作日值以获得下一个最近的日期?

Sar*_*avu 1

您的样本表

create table #t
(
    jobId int,
    personId int,
    frequencyVal varchar(10)
);

insert into #t values (1,100,'Mondays'),(2,101,'Saturdays');
Run Code Online (Sandbox Code Playgroud)

查询 1:为特定工作日选择当月最近 4 周的天数

-- Gets first day of month
DECLARE @FIRSTDAY DATE=DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)

;WITH  CTE as
(
     -- Will find all dates in current month
     SELECT CAST(@FIRSTDAY AS DATE) as DATES
     UNION ALL
     SELECT DATEADD(DAY,1,DATES)    
     FROM    CTE
     WHERE   DATES < DATEADD(MONTH,1,@FIRSTDAY)
 )
,CTE2 AS
(
   -- Join the #t table with  CTE on the datename+'s' 
   SELECT jobId,personId,frequencyVal,DATES,
   -- Get week difference for each weekday        
   DATEDIFF(WEEK,DATES,GETDATE()) WEEKDIFF,
   -- Count the number of weekdays in a month
   COUNT(DATES) OVER(PARTITION BY DATENAME(WEEKDAY,CTE.DATES)) WEEKCOUNT
   FROM CTE
   JOIN #t ON DATENAME(WEEKDAY,CTE.DATES)+'s' = #t.frequencyVal 
   WHERE MONTH(DATES)= MONTH(GETDATE())   
)
-- Converts to CSV and make sure that only nearest 4 week of days are generated for month
SELECT  DISTINCT C2.jobId,C2.personId,frequencyVal,
         SUBSTRING(
        (SELECT ', ' + CAST(DATEPART(MONTH,DATES) AS VARCHAR(2)) + '/'  + 
                       CAST(DATEPART(DAY,DATES) AS VARCHAR(2))
        FROM CTE2 
        WHERE C2.jobId=jobId AND C2.personId=personId AND C2.frequencyVal=frequencyVal AND
                       ((WEEKDIFF<3 AND WEEKDIFF>-3 AND WEEKCOUNT = 5) OR WEEKCOUNT <= 4)
        ORDER BY CTE2.DATES
        FOR XML PATH('')),2,200000) futureDates
FROM CTE2 C2
Run Code Online (Sandbox Code Playgroud)

例如,在 Query2 中最近的日期(这里我们以周六为例)

2015-Jan-10 will be 01/03,01/10,01/17,01/24
2015-Jan-24 will be 01/10,01/17,01/24,01/31
Run Code Online (Sandbox Code Playgroud)

查询 2:为特定工作日选择接下来 4 周的日期,与月份无关

;WITH  CTE as
(
     -- Will find the next 4 week details
     SELECT CAST(GETDATE() AS DATE) as DATES
     UNION ALL
     SELECT DATEADD(DAY,1,DATES)    
     FROM    CTE
     WHERE   DATES < DATEADD(DAY,28,GETDATE())
 )
,CTE2 AS
(
   -- Join the #t table with  CTE on the datename+'s' 
   SELECT jobId,personId,frequencyVal, DATES,
   ROW_NUMBER() OVER(PARTITION BY DATENAME(WEEKDAY,CTE.DATES) ORDER BY CTE.DATES) DATECNT
   FROM CTE
   JOIN #t ON DATENAME(WEEKDAY,CTE.DATES)+'s' = #t.frequencyVal  
)
-- Converts to CSV and make sure that only 4 days are generated for month
SELECT  DISTINCT C2.jobId,C2.personId,frequencyVal,   
        SUBSTRING(
        (SELECT ', ' + CAST(DATEPART(MONTH,DATES) AS VARCHAR(2)) + '/'  + 
                       CAST(DATEPART(DAY,DATES) AS VARCHAR(2))
        FROM CTE2 
        WHERE C2.jobId=jobId AND C2.personId=personId AND C2.frequencyVal=frequencyVal 
              AND DATECNT < 5
        ORDER BY CTE2.DATES
        FOR XML PATH('')),2,200000) futureDates
        FROM CTE2 C2
Run Code Online (Sandbox Code Playgroud)

GETDATE()如果(如果是星期六)是,以下将是输出

2015-01-05 - 1/10, 1/17, 1/24, 1/31
2015-01-24 - 1/24, 1/31, 2/7, 2/14
Run Code Online (Sandbox Code Playgroud)