【问题标题】:T SQL First Tuesday between date rangeT SQL 日期范围之间的第一个星期二
【发布时间】:2019-04-05 10:50:59
【问题描述】:

使用 SQL Server,我需要计算出“存储桶开始”日期和“存储桶结束”日期之间的第一个星期二。但是,我的代码返回了错误的日期。

这是我的代码:

SELECT 
    CONVERT(DATETIME, CONVERT(VARCHAR(10), [BUCKET_START])) AS  Bucket_Start,
    CONVERT(DATETIME, CONVERT(VARCHAR(10), [BUCKET_END])) AS Bucket_End,
    DATEADD(dd, - 6, DATEADD(wk, DATEDIFF(wk, 0, dateadd(dd, 7 - DATEPART(day, CONVERT(DATETIME, CONVERT(VARCHAR(10), [BUCKET_START]))),   
    CONVERT(DATETIME, CONVERT(VARCHAR(10), [BUCKET_END])))), 0)) AS [1st_Tuesday]
FROM 
    [BUCKETS]
WHERE 
    CAT_CODE = 1013
    AND BUCKET_START < CONVERT(NVARCHAR, GETDATE(), 112)
    AND BUCKET_END > CONVERT(NVARCHAR, GETDATE(), 112)

这些是目前的结果:

Bucket_Start      Bucket_End      1st_Tuesday
2019-03-31        2019-04-27      2019-03-26

但是,正确的 1st_Tuesday 是:

Bucket_Start      Bucket_End      1st_Tuesday
2019-03-31        2019-04-27      2019-04-02

为什么我的查询仍然在 3 月查找?

感谢您的帮助。

【问题讨论】:

  • 如果存储桶开始是星期日,则添加两天,星期一然后添加 1 天,依此类推。
  • @SAS - 不是重复的 - 我只想返回 1 条记录,该链接返回 4

标签: sql-server tsql date dateadd


【解决方案1】:

我们可以通过使用 case 语句来实现。

    SELECT 
CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])) AS Bucket_Start,
CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_END])) AS Bucket_End,
case when     abs((select  DATEparT(weekday  ,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))))) in  (1,2,3)
                  then    DATEadd(weekday,  3 -  abs((select  DATEparT(weekday  ,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))))), CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
                  else   DATEadd(weekday,  3 + ( 7 - abs((select  DATEparT(weekday  ,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))))), CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))  
                  end AS [1st_Tuesday]
FROM [BUCKETS]
WHERE   BUCKET_START < CONVERT(NVARCHAR, GETDATE(), 112)
AND BUCKET_END > CONVERT(NVARCHAR, GETDATE(), 112)

【讨论】:

    【解决方案2】:

    感谢大家的帮助!我已经选择了以下内容:

    SELECT
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) as Bucket_Start_Day, 
    CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])) AS Bucket_Start,
    CASE
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Sunday' then 
    DATEADD(DD,2,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Monday' then 
    DATEADD(DD,1,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Tuesday' then 
    CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Wednesday' then 
    DATEADD(DD,6,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Thursday' then 
    DATEADD(DD,5,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Friday' then 
    DATEADD(DD,4,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    WHEN
    DATENAME(dw,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START]))) = 'Saturday' then 
    DATEADD(DD,4,CONVERT(DATETIME, convert(VARCHAR(10), [BUCKET_START])))
    END AS '1st_Tuesday'
    FROM [BUCKETS]
    WHERE CAT_CODE = 1013
    AND BUCKET_START < CONVERT(NVARCHAR, GETDATE(), 112)
    AND BUCKET_END > CONVERT(NVARCHAR, GETDATE(), 112)
    

    这给了我以下信息:

    Bucket_Start_Day    Bucket_Start               1st_Tuesday
    Sunday          2019-03-31 00:00:00.000    2019-04-02 00:00:00.000
    

    【讨论】:

      【解决方案3】:

      这并不完全符合您的要求,但我相信您可以使用它来获得所需的结果。

      DECLARE  @Day INT = 3;
       --Sunday    1
       --Monday    2
       --Tuesday   3
       --Wednesday 4
       --Thurday   5
       --Friday    6
       --Saturday  7 
       DECLARE  @StartDate DATETIME = GETDATE();
      
       SELECT  DATEADD(DD, @Day - DATEPART(WEEKDAY, @StartDate) + IIF(@Day - DATEPART(WEEKDAY, @StartDate) >= 0, 0, 7), @StartDate)
      

      如果您希望下一个不包括今天,请将 >= 更改为 >

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-01
        • 2017-12-08
        • 1970-01-01
        • 2017-12-20
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多