获取“一天中的第几周”?

时间:2020-09-18 02:48:59

标签: sql sql-server database date

我有一个类似'2020-09-17'的日期,我想要这样:'Third Tuesday-2020-09-17',其中“ Third”代表17/09是9月的第三个星期二。

是否有使用SQL Server解决此问题的想法?

3 个答案:

答案 0 :(得分:1)

我刚刚将这个功能拼凑在一起。 仅在SET DATEFIRST 1 时有效。修改此功能以使用星期一不是一周中第一天的日历是读者的一项练习(警告:doing so is non-trivial)。

SET DATEFIRST 1; -- Set Monday as the first day-of-week.

CREATE FUNCTION dbo.GetDayOfWeekInMonth( @date date )
RETURNS int
AS
BEGIN

    --SET DATEFIRST 1; -- can't use this inside a function

    DECLARE @dayOfMonth            int  = DATEPART( day    , @date );
    DECLARE @dayOfWeek             int  = DATEPART( weekday, @date );

    DECLARE @startOfMonth          date = DATEFROMPARTS( YEAR( @date ), MONTH( @date ), 1 );
    DECLARE @startOfMonthDayOfWeek int  = DATEPART( weekday, @startOfMonth );

    DECLARE @weekNumber            int  = @dayOfMonth / 7;

    DECLARE @dayOfWeekInMonth      int  = CASE WHEN @startOfMonthDayOfWeek > @dayOfWeek THEN @weekNumber ELSE ( @weekNumber + 1 ) END;
    RETURN @dayOfWeekInMonth

END

示例:

所以运行这个:

SET DATEFIRST 1

DECLARE @t TABLE ( Dt date NOT NULL, DoW int NOT NULL, DoWName nvarchar(20) NOT NULL, DoWoM int NOT NULL );

DECLARE @d int = 1
WHILE @d <= 30
BEGIN
    
    DECLARE @dt date = DATEFROMPARTS( 2020, 9, @d );

    INSERT INTO @t ( Dt, DoW, DoWName, DoWoM )
    VALUES (
        @dt,
        DATEPART( weekday, @dt ),
        DATENAME( weekday, @dt ),
        dbo.GetDayOfWeekInMonth( @dt )
    );

    SET @d = @d + 1

END;

SELECT
    *,
    CASE DoWoM
        WHEN 1 THEN CONCAT( 'First ' , DoWName, ' of ', DATENAME( month, Dt ) )
        WHEN 2 THEN CONCAT( 'Second ', DoWName, ' of ', DATENAME( month, Dt ) )
        WHEN 3 THEN CONCAT( 'Third ' , DoWName, ' of ', DATENAME( month, Dt ) )
        WHEN 4 THEN CONCAT( 'Fourth ', DoWName, ' of ', DATENAME( month, Dt ) )
        WHEN 5 THEN CONCAT( 'Fifth ' , DoWName, ' of ', DATENAME( month, Dt ) ) ELSE NULL
    END AS [Text]
FROM
    @t;

给我这个输出:

Dt            DoW    DoWName    DoWoM    Text
2020-09-01    2      Tuesday    1        First Tuesday of September
2020-09-02    3      Wednesday  1        First Wednesday of September
2020-09-03    4      Thursday   1        First Thursday of September
2020-09-04    5      Friday     1        First Friday of September
2020-09-05    6      Saturday   1        First Saturday of September
2020-09-06    7      Sunday     1        First Sunday of September
2020-09-07    1      Monday     1        First Monday of September
2020-09-08    2      Tuesday    2        Second Tuesday of September
2020-09-09    3      Wednesday  2        Second Wednesday of September
2020-09-10    4      Thursday   2        Second Thursday of September
2020-09-11    5      Friday     2        Second Friday of September
2020-09-12    6      Saturday   2        Second Saturday of September
2020-09-13    7      Sunday     2        Second Sunday of September
2020-09-14    1      Monday     2        Second Monday of September
2020-09-15    2      Tuesday    3        Third Tuesday of September
2020-09-16    3      Wednesday  3        Third Wednesday of September
2020-09-17    4      Thursday   3        Third Thursday of September
2020-09-18    5      Friday     3        Third Friday of September
2020-09-19    6      Saturday   3        Third Saturday of September
2020-09-20    7      Sunday     3        Third Sunday of September
2020-09-21    1      Monday     3        Third Monday of September
2020-09-22    2      Tuesday    4        Fourth Tuesday of September
2020-09-23    3      Wednesday  4        Fourth Wednesday of September
2020-09-24    4      Thursday   4        Fourth Thursday of September
2020-09-25    5      Friday     4        Fourth Friday of September
2020-09-26    6      Saturday   4        Fourth Saturday of September
2020-09-27    7      Sunday     4        Fourth Sunday of September
2020-09-28    1      Monday     4        Fourth Monday of September
2020-09-29    2      Tuesday    5        Fifth Tuesday of September
2020-09-30    3      Wednesday  5        Fifth Wednesday of September

答案 1 :(得分:0)

我不得不在下面更改此代码的实现,因为以前的解决方案不适用于某些日期,例如2020-07-13,此时thar返回1而不是预期的2。当然,在那儿我需要一些“调教之手”,但有一段时间我正在使用它来填充日历表。

create function dbo.getdayofweekinmonth( @date date )  
returns int  
as  
begin  
    declare @dayofweek             int  = (datepart(dw, @date) + @@datefirst + 6 - 1) % 7 + 1;  
    declare @startofmonth          date = datefromparts( year( @date ), month( @date ), 1 );  

    declare @month_days as table (d int) -- d as day number
    while @startofmonth <= @date 
    begin
        insert into @month_days values ((datepart(dw, @startofmonth) + @@datefirst + 6 - 1) % 7 + 1); 
        select @startofmonth = dateadd(day, 1, @startofmonth);
    end

    return (select count(*) from @month_days where d = @dayofweek)
end

答案 2 :(得分:0)

为获得更高的性能,最好使用“日期维度表”并将其与您自己的表联接(“日期维度”表每天都有一条记录,并且包含您需要的有关特定日期的所有信息)

相关问题