【问题标题】:Get previous Tuesday (or any given day of week) for specified date获取指定日期的上周二(或一周中的任何一天)
【发布时间】:2016-01-09 20:27:35
【问题描述】:

我想获取指定日期的前一个星期二(或一周中的任何一天)。以下是周二的示例输入和预期输出:

CREATE TABLE #temp(testdate DATETIME);
INSERT INTO  #temp(testdate) VALUES
    ('2015-10-06 01:15'), -- Tue -> Tue 2015-10-06 00:00
    ('2015-10-07 04:30'), -- Wed -> Tue 2015-10-06 00:00
    ('2015-10-08 00:30'), -- Thu -> Tue 2015-10-06 00:00
    ('2015-10-09 21:00'), -- Fri -> Tue 2015-10-06 00:00
    ('2015-10-10 19:00'), -- Sat -> Tue 2015-10-06 00:00
    ('2015-10-11 01:15'), -- Sun -> Tue 2015-10-06 00:00
    ('2015-10-12 13:00'), -- Mon -> Tue 2015-10-06 00:00

    ('2015-10-13 18:45'), -- Tue -> Tue 2015-10-13 00:00
    ('2015-10-14 12:15'), -- Wed -> Tue 2015-10-13 00:00
    ('2015-10-15 10:45'), -- Thu -> Tue 2015-10-13 00:00
    ('2015-10-16 04:30'), -- Fri -> Tue 2015-10-13 00:00
    ('2015-10-17 12:15'), -- Sat -> Tue 2015-10-13 00:00
    ('2015-10-18 00:30'), -- Sun -> Tue 2015-10-13 00:00
    ('2015-10-19 10:45'), -- Mon -> Tue 2015-10-13 00:00

    ('2015-10-20 01:15'), -- Tue -> Tue 2015-10-20 00:00
    ('2015-10-21 23:45'), -- Wed -> Tue 2015-10-20 00:00
    ('2015-10-22 21:00'), -- Thu -> Tue 2015-10-20 00:00
    ('2015-10-23 18:45'), -- Fri -> Tue 2015-10-20 00:00
    ('2015-10-24 06:45'), -- Sat -> Tue 2015-10-20 00:00
    ('2015-10-25 06:45'), -- Sun -> Tue 2015-10-20 00:00
    ('2015-10-26 04:30'); -- Mon -> Tue 2015-10-20 00:00

DECLARE @clampday AS INT = 3; -- Tuesday
SELECT -- DATEADD/DATEPART/@clampday/???

使用 T-SQL 获取前一个星期二(或一周中的任何一天)的最合适方法是什么?

【问题讨论】:

标签: sql sql-server sql-server-2008 tsql datetime


【解决方案1】:

希望对你有帮助

SELECT DATEADD(day,- (DATEPART(dw, testdate) + @@DATEFIRST - 3) % 7,testdate) AS Saturday  
from #temp

SELECT DATENAME(weekday,DATEADD(day,- (DATEPART(dw, testdate) + @@DATEFIRST - 3) % 7,testdate)) +'  '+ 
        CONVERT(nvarchar,DATEADD(day,- (DATEPART(dw, testdate) + @@DATEFIRST - 3) % 7,testdate),101) AS Saturday
from @temp

输出将在以下格式

Saturday
Tuesday  10/06/2015

备注:整个查询只是DATEFIRSTDATEPARTDATEADD的组合计算来操纵时间

【讨论】:

  • @SalmanA DATEFIRST 指定一周的第一天。美国英语默认值为 7,星期日。 DATEPART 返回一个整数,表示指定日期的指定日期部分。 DATEADD 返回指定的日期,并将指定的数字间隔(有符号整数)添加到该日期的指定日期部分。整个查询只是时间的组合和计算
  • 这是我在 SO 上看到的最优雅的答案之一
【解决方案2】:

您可以使用DATEPART 获取周数,然后在下面使用CASE 语句:

SELECT
    testdate,
    CASE DATEPART(dw,testdate)  WHEN 1 THEN DATEADD(dd,-5,testdate) 
                                WHEN 2 THEN DATEADD(dd,-6,testdate) 
                                WHEN 3 THEN DATEADD(dd, 0,testdate) 
                                WHEN 4 THEN DATEADD(dd,-1,testdate) 
                                WHEN 5 THEN DATEADD(dd,-2,testdate) 
                                WHEN 6 THEN DATEADD(dd,-3,testdate) 
                                WHEN 7 THEN DATEADD(dd,-4,testdate)                                     
    END
FROM #temp

根据@jpw 的评论,你必须在下面将DATEFIRST 设置为7(默认):

SET DATEFIRST 7

【讨论】:

    【解决方案3】:

    最有效的方法是使用 DATEADD 和 DATEDIFF:

    这就是你需要的所有代码,它也适用于其他工作日

    DECLARE @daystoadd int = 1 -- tuesday
    
    
    SELECT DATEADD(week, datediff(d, @daystoadd, testdate) / 7, @daystoadd)
    FROM #temp
    

    【讨论】:

      【解决方案4】:
      CREATE PROC FIND_TUESDAY_DATE
      (
       @MYDATE DATE
      )
      AS 
      BEGIN
          SELECT CASE 
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,0,@MYDATE) AS DATE)) = 'Tuesday' OR DATENAME(DW,CAST(DATEADD(DAY,-7,@MYDATE) AS DATE))  = 'Tuesday' 
                  THEN CAST(DATEADD(DAY,-7,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-1,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-1,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-2,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-2,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-3,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-3,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-4,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-4,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-5,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-5,@MYDATE) AS DATE)
                  WHEN DATENAME(DW,CAST(DATEADD(DAY,-6,@MYDATE) AS DATE) ) = 'Tuesday' THEN CAST(DATEADD(DAY,-6,@MYDATE) AS DATE)
              END
      END
      GO
      

      【讨论】:

        【解决方案5】:

        如果仍有帮助,请回答一些细节:

        declare @given_date datetime = '2015-10-15 00:30'
        declare @required_weekday int = 1 -- tuesday
        
        select dateadd(week, datediff(week, 0, @given_date), @required_weekday)
        

        解释:

        1. datediff(week, 0, @given_date):返回 1900-01-01given_date 之间的 number_of_weeks
        2. dateadd(week, number_of_weeks, @required_weekday):将计算出的 number_of_weeks 和给定的 required_weekday 添加到初始日历日期 1900-01-01

        【讨论】:

          猜你喜欢
          • 2019-03-31
          • 1970-01-01
          • 1970-01-01
          • 2017-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-22
          相关资源
          最近更新 更多