• Get first day of week in SQL Server


    Get first day of week in SQL Server

    回答1

    To answer why you're getting a Monday and not a Sunday:

    You're adding a number of weeks to the date 0. What is date 0? 1900-01-01. What was the day on 1900-01-01? Monday. So in your code you're saying, how many weeks have passed since Monday, January 1, 1900? Let's call that [n]. Ok, now add [n] weeks to Monday, January 1, 1900. You should not be surprised that this ends up being a Monday. DATEADD has no idea that you want to add weeks but only until you get to a Sunday, it's just adding 7 days, then adding 7 more days, ... just like DATEDIFF only recognizes boundaries that have been crossed. For example, these both return 1, even though some folks complain that there should be some sensible logic built in to round up or down:

    SELECT DATEDIFF(YEAR, '2010-01-01', '2011-12-31');
    SELECT DATEDIFF(YEAR, '2010-12-31', '2011-01-01');
    

    To answer how to get a Sunday:

    If you want a Sunday, then pick a base date that's not a Monday but rather a Sunday. For example:

    DECLARE @dt DATE = '1905-01-01';
    SELECT [start_of_week] = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP), @dt);
    

    This will not break if you change your DATEFIRST setting (or your code is running for a user with a different setting) - provided that you still want a Sunday regardless of the current setting. If you want those two answers to jive, then you should use a function that does depend on the DATEFIRST setting, e.g.

    SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
    

    So if you change your DATEFIRST setting to Monday, Tuesday, what have you, the behavior will change. Depending on which behavior you want, you could use one of these functions:

    CREATE FUNCTION dbo.StartOfWeek1 -- always a Sunday
    (
        @d DATE
    )
    RETURNS DATE
    AS
    BEGIN
        RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
    END
    GO
    

    ...or...

    CREATE FUNCTION dbo.StartOfWeek2 -- always the DATEFIRST weekday
    (
        @d DATE
    )
    RETURNS DATE
    AS
    BEGIN
        RETURN (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, @d), @d));
    END
    GO
    

    Now, you have plenty of alternatives, but which one performs best? I'd be surprised if there would be any major differences but I collected all the answers provided so far and ran them through two sets of tests - one cheap and one expensive. I measured client statistics because I don't see I/O or memory playing a part in the performance here (though those may come into play depending on how the function is used). In my tests the results are:

    "Cheap" assignment query:

    Function - client processing time / wait time on server replies / total exec time
    Gandarez     - 330/2029/2359 - 0:23.6
    me datefirst - 329/2123/2452 - 0:24.5
    me Sunday    - 357/2158/2515 - 0:25.2
    trailmax     - 364/2160/2524 - 0:25.2
    Curt         - 424/2202/2626 - 0:26.3
    

    "Expensive" assignment query:

    Function - client processing time / wait time on server replies / total exec time
    Curt         - 1003/134158/135054 - 2:15
    Gandarez     -  957/142919/143876 - 2:24
    me Sunday    -  932/166817/165885 - 2:47
    me datefirst -  939/171698/172637 - 2:53
    trailmax     -  958/173174/174132 - 2:54
    

    I can relay the details of my tests if desired - stopping here as this is already getting quite long-winded. I was a bit surprised to see Curt's come out as the fastest at the high end, given the number of calculations and inline code. Maybe I'll run some more thorough tests and blog about it... if you guys don't have any objections to me publishing your functions elsewhere.

    回答2

    For these that need to get:

    Monday = 1 and Sunday = 7:

    SELECT 1 + ((5 + DATEPART(dw, GETDATE()) + @@DATEFIRST) % 7);
    

    Sunday = 1 and Saturday = 7:

    SELECT 1 + ((6 + DATEPART(dw, GETDATE()) + @@DATEFIRST) % 7);
    

    Above there was a similar example, but thanks to double "%7" it would be much slower.

  • 相关阅读:
    intent-filter的用法
    关于三星手机刷机,以GTN8000为例
    seamless video loop with videoview
    hashmap,list,vector,Linkedlist的优缺点
    vlc+mfc,搭建简单的播放器
    OA项目9:部门管理的上下级部门的功能实现
    OA项目8:表映射关系及跟对象之间的关系处理
    OA项目7:系统管理之部门管理
    OA项目6:项目优化
    OA项目5:系统管理之岗位管理
  • 原文地址:https://www.cnblogs.com/chucklu/p/15802266.html
Copyright © 2020-2023  润新知