Trovare ultima domenica

Come farà a trovare ultima domenica del mese in sql 2000?

InformationsquelleAutor Adu | 2009-11-25



10 Replies
  1. 14
    SELECT
     DATEADD(day,DATEDIFF(day,'19000107',DATEADD(month,DATEDIFF(MONTH,0,GETDATE() /*YourValuehere*/),30))/7*7,'19000107')

    Edit: Una corretta e definitiva, di lavoro, di risposta da un mio collega.

    • Errore, datediff richiede 3 argomenti …
    • Per favore qualcuno può spiegare come funziona? In particolare, perche ‘19000107’ e ‘il 30’ sono utilizzati in DATEADD e DATEDIFF funzioni rispettivamente? Grazie.
  2. 2

    Un approccio alternativo, preso in prestito dalla data warehousing pratica. Creare un data-tabella di dimensione e di pre-caricare per 10 anni, o giù di lì.

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

    Il modo più semplice per compilare la dimDate è quello di trascorrere un pomeriggio con Excel e poi importare il DB da lì. Un semi-decente dimDate tabella 50+ colonne — qualcosa che hai sempre voluto sapere su una data.

    A questo punto, la domanda diventa qualcosa di simile a:

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

    Essenzialmente, tutte le query correlate a diventare più semplice.

  3. 2

    Domenica prossima, in SQL, indipendentemente da quale giorno è il primo giorno della settimana: restituisce 2011-01-02 23:59:59.000, 22-dic-2010:

    select DateADD(ss, -1, DATEADD(week, DATEDIFF(week, 0, getdate()), 14))
  4. 1
    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)
    • non riesce per la maggior parte dei non-CI-installazioni in lingua inglese…
  5. 1

    Trovo alcune di queste soluzioni è difficile capire quindi, ecco la mia versione con le variabili per spiegare i passaggi.

    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[email protected]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. 0

    Porca vacca, questo è brutto, ma qui va:

    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)))
  7. 0

    Qui è il modo corretto, la contabilità per @@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

Lascia un commento