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.
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ì.
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 =11AND Year =2009;
Essenzialmente, tutte le query correlate a diventare più semplice.
Qui è il modo corretto, la contabilità per @@DATEFIRST
IFNOTEXISTS(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'))BEGINEXECUTE(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-- =====================================================================ALTERFUNCTION[dbo].[fu_dtLastSundayInMonth](@in_DateTime datetime )
RETURNS DateTime
ASBEGIN-- Abrunden des Eingabedatums auf 00:00:00 UhrDECLARE@dtReturnValue AS DateTime
-- 26.12.9999 SOIF@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
Edit: Una corretta e definitiva, di lavoro, di risposta da un mio collega.
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ì.
Il modo più semplice per compilare la
dimDate
è quello di trascorrere un pomeriggio con Excel e poi importare il DB da lì. Un semi-decentedimDate
tabella 50+ colonne — qualcosa che hai sempre voluto sapere su una data.A questo punto, la domanda diventa qualcosa di simile a:
Essenzialmente, tutte le query correlate a diventare più semplice.
Domenica prossima, in SQL, indipendentemente da quale giorno è il primo giorno della settimana: restituisce 2011-01-02 23:59:59.000, 22-dic-2010:
Trovo alcune di queste soluzioni è difficile capire quindi, ecco la mia versione con le variabili per spiegare i passaggi.
Porca vacca, questo è brutto, ma qui va:
Primo costruito un riscontro tabella.
http://www.sqlservercentral.com/articles/T-SQL/62867/
quindi ottenere ciò che si vuole..
http://www.sqlservercentral.com/Forums/Topic515226-1291-1.aspx
Qui è il modo corretto, la contabilità per @@DATEFIRST