5

有没有办法使用 T-SQL 语法找出每月第二个星期二的日期?

例如,3 月是 12 日,4 月是 9 日。

4

4 回答 4

3

在不知道实际所需的输入和输出是什么的情况下,我现在只能给您一个用于将日期标识为该月的第二个星期二的谓词:

DATEPART(day,@Date) between 8 and 14 and --Find the second one in the month
DATEPART(weekday,@Date) = DATEPART(weekday,'20130319') --Make sure its a Tuesday

(我使用固定的,已知的星期二,以避免DATEFIRST在查询运行时必须知道哪些设置有效)


这会找到当月的适当星期二,但显然@Date可以设置为任何感兴趣的日期:

declare @Date datetime
set @Date =  CURRENT_TIMESTAMP

;with Numbers as (select n from (values (0),(1),(2),(3),(4),(5),(6)) t(n)),
PotentialDates as (select DATEADD(day,n,DATEADD(month,DATEDIFF(month,'20010101',@Date),'20010108')) as Date
from Numbers
)
select * from PotentialDates where DATEPART(weekday,Date) = DATEPART(weekday,'20130319')

(而且,希望也很明显,查询可以是更大查询的一部分,@Date而不是列值,因此这可以构成整个工作的基于集合的方法的一部分)

于 2013-03-22T07:42:41.140 回答
3

这就是您如何找到 2013 年所有“第二个星期二”的方法。

select 
dateadd(day, 8, datediff(day, 1, dateadd(month, n, '2013-01-07')) / 7 * 7) date
from 
(values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)) t(n)
于 2013-03-22T08:54:40.077 回答
1

此代码将在每月的第 1 和第 3 个星期日为您提供。

declare @dt datetime
select @dt = '12/01/2014'

select dateadd(mm,datediff(mm,'',@dt),'') - datepart(dw,dateadd(mm,datediff(mm,'',@dt),'')+0)+ 8
select dateadd(mm,datediff(mm,'',@dt),'') - datepart(dw,dateadd(mm,datediff(mm,'',@dt),'')+0)+ 22
于 2014-01-17T06:37:14.157 回答
1

从星期日开始的几个月内,以前的答案都不起作用(它指向第二个星期日)。

SELECT @dt AS input_date,

    DATEADD(mm, DATEDIFF(mm, 0, @dt), 0) --truncate date to month start

    -- DATEPART(@month_start) returns month start's weekday, with Sunday starting 1;
    -- Since Sunday starts at 1, we need to perform proper adjustment - move date 6 days forward (7 week days - 1 for sunday) forward and find its datepart, which will be 7
    -- Result: month starting sunday, datepart returns 7; month starting Mon we return 1 (datepart of Mon + 6 days = Sunday, which is 1), month starting tue, we return 2
    -- Effectivelly, datepart offset will always point last Sunday of previous month
    - DATEPART(dw, 
            6
            + DATEADD(mm,datediff(mm,0,@dt),0) --truncate date to month start
        ) 
        
    -- Since we found last Sunday of previous month, we need to add 7
    + 7 AS CORRECT,

    dateadd(mm,datediff(mm,'',@dt),'') - datepart(dw,dateadd(mm,datediff(mm,'',@dt),'')+0)+ 8 AS sometimes_correct

显示相对于 Pravin Pandit 答案的正确答案的图像:

1

我们可以扩展查找本月第一个星期二的基本原理,并创建一个执行此操作的函数,因此对于任何输入日期,它都会找到该月的第一个星期二:

ALTER FUNCTION dbo.f_time_floor_1st_tue(@date DATETIME2(3))
RETURNS DATETIME
AS
BEGIN
    RETURN 
    
            DATEADD(mm, DATEDIFF(mm, 0, @date), 0) --truncate date to month start

        -- DATEPART(@month_start) returns month start's weekday, with Sunday starting 1;
        -- Since Sunday starts at 1, we need to perform proper adjustment - move date 6 days forward (7 week days - 1 for sunday) forward and find its datepart, which will be 7
        -- Result: month starting sunday, datepart returns 7; month starting Mon we return 1 (datepart of Mon + 6 days = Sunday, which is 1), month starting tue, we return 2
        -- Effectivelly, datepart offset will always point last Sunday of previous month
        -- Extending this logic for finding first Tuesday, Tuesday should always return 7 we need to move Tue datepart (3) by 4  ( which is 7 days in the week minus 3 
        - DATEPART(dw, 
                4 -- 4 is adjustment so that DATEPART returns 7 for all months starting Tue
                + DATEADD(mm,datediff(mm,0,@date),0) --truncate date to month start
            ) 
        
        -- Since we found last weekday of previous month, we need to add 7
        + 7
    
    ;
END;
GO
于 2021-02-04T18:00:18.927 回答