2008-10-08 106 views
6

Konkretnie MSSQL 2005.Jak obliczyć ostatni dzień miesiąca w SQL?

+0

Nie jestem pewna odpowiedź, oznaczone jako przyjęte acutally działa . Uruchomić "2009 Jan 30" przez to i zobaczyć, co daje? – MatBailie

+0

Witaj? Przyjęta odpowiedź - nie działa ... – MatBailie

+0

Dems, użyłem tego jako inspiracji dla rozwiązania, które wdrożyłem, ale to prawie rok temu, więc nie pamiętam dokładnie, co zrobiłem ... –

Odpowiedz

17

Oto rozwiązanie, które daje ostatniej sekundzie bieżącego miesiąca. Możesz wyodrębnić część daty lub zmodyfikować ją, aby wrócić tylko dzień. Przetestowałem to na SQL Server 2005.

select dateadd(s, -1, dateadd(mm, datediff(m, 0, getdate()) + 1, 0)); 

Aby zrozumieć, jak to działa musimy spojrzeć na funkcje dateadd() i datediff().

DATEADD(datepart, number, date) 
DATEDIFF(datepart, startdate, enddate) 

przypadku uruchomienia tylko najbardziej wewnętrzne wezwanie do DateDiff(), pojawi się aktualny numer miesiąca od datownik 0.

select datediff(m, 0, getdate()); 
1327 

Kolejna część dodaje, że kilka miesięcy plus 1 do 0 znacznik czasu, podając punkt początkowy następnego miesiąca kalendarzowego.

select dateadd(mm, datediff(m, 0, getdate()) + 1, 0); 
2010-09-01 00:00:00.000 

Wreszcie zewnętrzna DateAdd() po prostu odejmuje jeden sekund od początku znacznika czasu następnego miesiąca, co daje w ostatniej sekundzie bieżącego miesiąca.

select dateadd(s, -1, dateadd(mm, datediff(m, 0, getdate()) + 1, 0)); 
2010-08-31 23:59:59.000 


Ten stary odpowiedź (poniżej) ma błąd, który nie działa na ostatni dzień miesiąca, który ma dni więcej niż następnego miesiąca. Zostawiam to tutaj jako ostrzeżenie dla innych.

Dodaj miesiąc do bieżącej daty, a następnie odejmij wartość zwróconą przez funkcję DZIEŃ zastosowaną do bieżącej daty, używając funkcji DZIEŃ i DATA DATA.

dateadd(day, -day(getdate()), dateadd(month, 1, getdate())) 
+0

Co się stanie, jeśli dwie wywołania getdate dadzą odpowiedzi w różnych terminach? –

+0

Przypuszczam, że to możliwe. Będziesz musiał wcześniej zadeklarować zmienną, która będzie zawierała dzisiejszą datę. –

+0

Nie zrobią tego. Tworzymy raporty generujące kolumny: rok, kwartał, miesiąc i rundate (GetDate()), które trwają 30 sekund, a wartość nigdy się nie zmienia. – JeffO

3

Spróbuj tego:

DATEADD (DAY, -1, DATEADD (MONTH, DATEDIFF (MONTH, 0, CURRENT_TIMESTAMP) + 1, 0) 
+1

Często stwierdzam, że ludzie nie przestrzegają logiki tego. Tak więc, chociaż wydaje się, że jest poprawny (jeśli zaakceptowana odpowiedź wydaje się być nieprawidłowa), nie dam +1. Czy jest szansa, że ​​możesz edytować odpowiedź, aby podać wyjaśnienie? – MatBailie

0
DECLARE 
    @Now datetime, 
    @Today datetime, 
    @ThisMonth datetime, 
    @NextMonth datetime, 
    @LastDayThisMonth datetime 

SET @Now = getdate() 
SET @Today = DateAdd(dd, DateDiff(dd, 0, @Now), 0) 
SET @ThisMonth = DateAdd(mm, DateDiff(mm, 0, @Now), 0) 
SET @NextMonth = DateAdd(mm, 1, @ThisMonth) 
SET @LastDayThisMonth = DateAdd(dd, -1, @NextMonth) 

Czasami naprawdę potrzebują ostatni dzień tego miesiąca, ale często to, czego naprawdę chcę to opisać interwał czasowy tym miesiącu. Jest to najlepszy sposób na opisanie interwał czasie tego miesiąca:

WHERE @ThisMonth <= someDate and someDate < @NextMonth 
4
SELECT DATEADD(M, DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), '1990-01-31T00:00:00.000') 

Objaśnienie:

ogólne podejście: użyj funkcji czasowej.

SELECT '1990-01-01T00:00:00.000', '1990-01-31T00:00:00.000' 

Są literałami Datetime, jako pierwszy czas granulatu w pierwszym dniu i ostatnim dniu, odpowiednio, w tym samym 31-dniowego miesiąca. Który miesiąc jest wybrany jest całkowicie arbitralny.

SELECT DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP) 

Jest to różnica w całych miesiącach między pierwszym dniem miesiąca odniesienia a bieżącym znacznikiem czasu. Nazwijmy to @calc.

SELECT DATEADD(M, @calc, '1990-01-31T00:00:00.000') 

Dodaje @calc miesiąc granulki do ostatniego dnia miesiąca odniesienia, wynikiem których jest obecny timestamp „zaokrąglone” do ostatniego dnia swojego miesiąca. Q.E. D.

+0

+1 za dołączenie wyjaśnienia :) – MatBailie

0

Dla kompletności w Oracle chcesz zrobić coś takiego ...

select add_months(trunc(sysdate,'MM'),1) ... 

lub

select last_day(sysdate)+1 ... 
0
DATEADD(dd, -1, DATEADD(mm, +1, DATEADD(dd, 1 - DATEPART(dd, @myDate), @myDate))) 
2

one kluczowe punkty, jeśli można dostać pierwszy dzień prądu miesiąc, ostatni dzień ostatniego miesiąca i ostatni dzień bieżącego miesiąca.

Poniżej krok po kroku sposób napisać zapytanie:

w SQL Server Data rozpoczyna się od 1901/01/01 (Date 0) i do tej pory w każdym miesiącu może być identyfikowany przez numer. 12 miesiąc to pierwszy miesiąc 1902 r. Oznacza styczeń. Miesiąc 1200 to styczeń 2001 roku. Podobnie każdy dzień może być przypisany przez unikalną liczbę np. Data 0 to 1901/01/01. Data 31 jest 01/02/1901 w styczniu 1901 roku rozpocznie się od 0.

Aby dowiedzieć Pierwszy dzień bieżącego miesiąca (bieżącą datę lub dany dzień)

  1. najpierw musimy sprawdzić, jak wiele miesięcy minęło od daty 0 (1901/01/01). SELECT DateDiff (MM, 0, GETDATE())
  2. Dodaj samą liczbę od miesiąca do tej pory 0 (1901/01/01)

    SELECT DATEADD (MM, DateDiff (MM, 0, GETDATE()), 0)

Potem dostanie pierwszy dzień bieżącego miesiąca (bieżącą datę lub dany dzień)

Aby uzyskać ostatniego dnia ostatniego miesiąca

Musimy odjąć drugi od pierwszego dnia bieżącego miesiąca

SELECT DATEADD (SS 1, DATEADD (MM DATEDIFF (MM 0 GETDATE()), 0))

Aby uzyskać ostatniego dnia bieżącego miesiąca

Aby uzyskać pierwszy dzień bieżącego miesiąca najpierw sprawdzenie, ile miesięcy zostały przekazane od daty 0 (1901/01/01).Jeśli dodamy kolejny miesiąc z łącznymi miesiącami od daty 0, a następnie dodamy całkowite miesiące z datą 0, otrzymamy pierwszy dzień następnego miesiąca.

SELECT DATEADD(MM, DATEDIFF(MM,0,GETDATE())+1,0) 

Jeśli mamy pierwszy dzień następnego miesiąca, a następnie dostać się ostatni dzień bieżącego miesiąca, wszyscy musimy odjąć sekundy.

SELECT DATEADD (SS 1, DATEADD (MM DATEDIFF (MM 0 GETDATE()) + 1,0))

nadziei, że pomaga.

1

Korzystając z SQL2005, nie masz dostępu do przydatnej funkcji EOMONTH(), więc musisz to obliczyć samodzielnie.

Ta prosta funkcja wola działa podobnie do EOMONTH

CREATE FUNCTION dbo.endofmonth(@date DATETIME= NULL) 
RETURNS DATETIME 
BEGIN 
RETURN DATEADD(DD, -1, DATEADD(MM, +1, DATEADD(DD, 1 - DATEPART(DD, ISNULL(@date,GETDATE())), ISNULL(@date,GETDATE())))) 
END 

Zapytanie wykonać:

SELECT dbo.endofmonth(DEFAULT) --Current month-end date 
SELECT dbo.endofmonth('02/25/2012') --User-defined month-end date 
Powiązane problemy