【问题标题】:Find last sunday查找上周日
【发布时间】:2010-12-20 03:56:03
【问题描述】:

如何在 sql 2000 中找到一个月的最后一个星期日?

【问题讨论】:

    标签: sql sql-server tsql sql-server-2000


    【解决方案1】:
    SELECT
     DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,GETDATE() /*YourValuehere*/),30))/7*7,'19000107')
    

    编辑:我的同事给出的正确、最终、有效的答案。

    【讨论】:

    • 有人能解释一下这是如何工作的吗?具体来说,为什么在 DATEADD 和 DATEDIFF 函数中分别使用 '19000107' 和 '30' ?谢谢。
    • @Sikander: 19000107 之所以被使用是因为January 7th, 1900 是遥远过去的任意星期日。
    • ... 为什么是30/7*7
    【解决方案2】:
    select dateadd(day,1-datepart(dw, getdate()), getdate())
    

    【讨论】:

    • 这只会返回上一个星期日,而不是当月的最后一个星期日。
    【解决方案3】:

    借鉴数据仓库实践的另一种方法。创建一个日期维度表并将其预加载 10 年左右。

    TABLE dimDate (DateKey, FullDate, Day, Month, Year, DayOfWeek, 
                   DayInEpoch, MonthName, LastDayInMonthIndicator, many more..)
    

    填写dimDate 的最简单方法是用Excel 度过一个下午,然后从那里导入数据库。 dimDate 半正派的表有 50 多列——任何你想知道的关于日期的信息。

    有了这个,问题就变成了这样:

    SELECT max(FullDate)
    FROM dimDate
    WHERE DayOfWeek = 'Sunday'
          AND Month = 11
          AND Year = 2009;
    

    基本上,所有与日期相关的查询都变得更简单了。

    【讨论】:

      【解决方案4】:

      SQL 中的下周日,无论哪一天是一周的第一天:在 2010 年 12 月 22 日返回 2011-01-02 23:59:59.000:

      select DateADD(ss, -1, DATEADD(week, DATEDIFF(week, 0, getdate()), 14))
      

      【讨论】:

        【解决方案5】:

        我发现其中一些解决方案很难理解,所以这是我的版本,其中包含变量来解释这些步骤。

        ALTER FUNCTION dbo.fn_LastSundayInMonth
        (
          @StartDate DATETIME
         ,@RequiredDayOfWeek INT    /* 1= Sunday */
        )
        RETURNS DATETIME
        AS
        /*
        A detailed step by step way to get the answer...
        
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,1)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,2)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,3)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,4)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,5)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,6)
        SELECT dbo.fn_LastSundayInMonth(getdate()-31,7)
        */
        BEGIN
            DECLARE @MonthsSince1900 INTEGER
            DECLARE @NextMonth INTEGER
            DECLARE @DaysToSubtract INTEGER
            DECLARE @FirstDayOfNextMonth DATETIME
            DECLARE @LastDayOfMonthDayOfWeek INTEGER
            DECLARE @LastDayOfMonth DATETIME
            DECLARE @ReturnValue DATETIME
        
            SET @MonthsSince1900=DateDiff(month, 0, @StartDate)
            SET @NextMonth=@MonthsSince1900+1
            SET @FirstDayOfNextMonth = DateAdd(month,@NextMonth, 0)
            SET @LastDayOfMonth = DateAdd(day, -1, @FirstDayOfNextMonth)
        
            SET @ReturnValue = @LastDayOfMonth
        
            WHILE DATEPART(dw, @ReturnValue) <> @RequiredDayOfWeek
                BEGIN
                    SET @ReturnValue = DATEADD(DAY,-1, @ReturnValue)
                END
        
            RETURN @ReturnValue
        END
        

        【讨论】:

          【解决方案6】:
          DECLARE @LastDateOfMonth smalldatetime
          SELECT @LastDateOfMonth = DATEADD(month, DATEDIFF(month, -1, GETDATE()), 0) -1
          Select DATEADD(dd,-( CASE WHEN DATEPART(weekday,@LastDateOfMonth) = 1 THEN 0 ELSE DATEPART(weekday,@LastDateOfMonth) - 1 END ),@LastDateOfMonth)
          

          【讨论】:

            【解决方案7】:

            天哪,这很丑,但是这里有:

            DECLARE @dtDate DATETIME
            SET @dtDate = '2009-11-05'
            
            SELECT DATEADD(dd, -1*(DATEPART(dw, DateAdd(day, -1, DateAdd(month, DateDiff(month, 0, @dtDate)+1, 0)))-1),
                        DateAdd(day, -1, DateAdd(month, DateDiff(month, 0, @dtDate)+1, 0)))
            

            【讨论】:

              【解决方案8】:

              首先建立了一个计数表。 http://www.sqlservercentral.com/articles/T-SQL/62867/ 然后得到你想要的..

              http://www.sqlservercentral.com/Forums/Topic515226-1291-1.aspx

              DECLARE @DateStart DATETIME,
                      @DateEnd   DATETIME
              
               SELECT @DateStart = '20080131',
                      @DateEnd   = '20101201'
              
               SELECT DATEADD(wk,DATEDIFF(wk,6,DATEADD(mm,DATEDIFF(mm,-1,DATEADD(mm,t.N-1,@DateStart)),-1)),6)
                 FROM dbo.Tally t
                WHERE t.N <= DATEDIFF(mm,@DateStart,@DateEnd)
              

              【讨论】:

                【解决方案9】:

                这是正确的方法,占@@DATEFIRST

                IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_dtLastSundayInMonth]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
                BEGIN
                    EXECUTE(N'CREATE FUNCTION [dbo].[fu_dtLastSundayInMonth]() RETURNS int BEGIN RETURN 0 END ')
                END 
                GO 
                
                
                
                /*
                SET DATEFIRST 3; -- Monday
                
                WITH CTE AS (
                
                    SELECT 1 AS i, CAST('20190101' AS datetime) AS mydate  
                    UNION ALL 
                
                    SELECT i+1 AS i, DATEADD(month, 1, CTE.mydate) AS mydate 
                    FROM CTE WHERE i < 100 
                )
                
                SELECT -666 AS i, dbo.fu_dtLastSundayInMonth('17530101') AS lastSundayInMonth, dbo.fu_dtLastSundayInMonth('17530101') AS Control 
                
                UNION ALL 
                
                SELECT -666 AS i, dbo.fu_dtLastSundayInMonth('99991231') AS lastSundayInMonth, dbo.fu_dtLastSundayInMonth('99991231') AS Control 
                
                UNION ALL 
                
                SELECT 
                     mydate 
                    ,dbo.fu_dtLastSundayInMonth(mydate) AS lastSundayInMonth 
                    ,dbo.fu_dtLastSundayInMonth(mydate) AS lastSundayInMonth 
                    ,DATEADD(day,DATEDIFF(day,'19000107', DATEADD(MONTH, DATEDIFF(MONTH, 0, mydate, 30))/7*7,'19000107') AS Control 
                FROM CTE 
                
                */
                
                
                -- =====================================================================
                -- Description:   Return date of last sunday in month
                --                of the same year and month as @in_DateTime
                -- =====================================================================
                ALTER FUNCTION [dbo].[fu_dtLastSundayInMonth](@in_DateTime datetime )
                RETURNS DateTime
                AS
                BEGIN
                    -- Abrunden des Eingabedatums auf 00:00:00 Uhr
                    DECLARE @dtReturnValue AS DateTime  
                    -- 26.12.9999   SO
                    IF @in_DateTime >= CAST('99991201' AS datetime) 
                        RETURN CAST('99991226' AS datetime); 
                
                    -- @dtReturnValue is now last day of month 
                    SET @dtReturnValue = DATEADD 
                        (
                             DAY 
                            ,-1
                            ,DATEADD
                            (
                                 MONTH
                                ,1
                                ,CAST(CAST(YEAR(@in_DateTime) AS varchar(4)) + RIGHT('00' + CAST(MONTH(@in_DateTime) AS varchar(2)), 2) + '01' AS datetime) 
                            )
                        )
                    ;
                
                    -- SET DATEFIRST 1 -- Monday - Super easy ! 
                    -- SET DATEFIRST != 1 - PHUK THIS ! 
                    SET @dtReturnValue = DATEADD
                                        (
                                            day
                                            ,
                                             -
                                             (
                
                                                (
                                                    -- DATEPART(WEEKDAY, @lastDayofMonth) -- with SET DATEFIRST 1 
                                                    DATEPART(WEEKDAY, @dtReturnValue) + @@DATEFIRST - 2 % 7 + 1 
                                                )
                                                %7
                                            )
                                            , @dtReturnValue
                    );
                
                    RETURN @dtReturnValue; 
                END
                
                
                GO
                

                【讨论】:

                  【解决方案10】:
                  select next_day(last_day(sysdate)-7, 'Sunday') from dual
                  

                  【讨论】:

                    猜你喜欢
                    • 2012-06-21
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-03-30
                    • 2021-02-13
                    • 1970-01-01
                    相关资源
                    最近更新 更多