Jak mogę wybrać pierwszy dzień miesiąca w SQL?

308

Muszę tylko wybrać pierwszy dzień miesiąca danej zmiennej datetime.

Wiem, że korzystanie z tego rodzaju kodu jest dość łatwe:

select CAST(CAST(YEAR(@mydate) AS VARCHAR(4)) 
+ '/' + CAST(MONTH(@mydate) AS VARCHAR(2)) + '/01' AS DATETIME)

Ale to nie jest zbyt eleganckie i prawdopodobnie też nie bardzo szybkie.

Czy jest na to lepszy sposób? Używam SQL Server 2008.

Brann
źródło

Odpowiedzi:

603
SELECT DATEADD(month, DATEDIFF(month, 0, @mydate), 0) AS StartOfMonth
Łukasz
źródło
63
Należy zauważyć, że błąd wspomniany przez Martina Smitha może „tylko” wpływać na wydajność, a nie na poprawność.
Olson.dev,
34
Jeśli ktoś się zastanawia SELECT EOMONTH(@mydate) AS EndOfMonth, poda ci ostatni dzień miesiąca.
hallizh
3
Jak mogę ustalić, czy zauważony błąd oszacowania liczności wpłynie na mnie? Jest oznaczony jako poprawiony w 2010 roku. Czy to oznacza, że ​​tylko SQL Server 2012 i nowsze są bezpieczne, czy też możliwe jest, że serwer 2008 został załatany?
Jon
134

Oprócz wszystkich powyższych odpowiedzi, sposób oparty na funkcji wprowadzonej w sql 2012

SELECT DATEFROMPARTS(YEAR(@mydate),MONTH(@mydate),1)
Jithin Shaji
źródło
62

Począwszy od SQL Server 2012:

SELECT DATEADD(DAY,1,EOMONTH(@mydate,-1))
Marcos Krucken
źródło
11
Wydaje się, że działa to tylko w 2012 roku i później. msdn.microsoft.com/en-us/library/hh213020.aspx
Josh Yeager
1
Ma tę zaletę, że wspomina datę źródłową tylko jeden raz, więc jest ładniejsza, jeśli pochodzi od wywołania funkcji.
Ian Horwill,
14

Rzutowanie ciągu (tj. „5/1/2009”) na datę i godzinę jest z pewnością bardziej czytelne, ale znaleźliśmy kod, który zwróciłby pierwszy miesiąc ...

DECLARE @Date DATETIME
//...
SELECT DATEADD(mm, DATEDIFF(mm,0,@Date), 0)
Mayo
źródło
10

Proste zapytanie:

SELECT DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0) 
-- Instead of GetDate you can put any date.
Abhishek Gupta
źródło
6

Prawdopodobnie jest dość szybki. Dlaczego nie utworzyć go jako funkcji SQL.

CREATE FUNCTION [dbo].[GetFirstDayOfMonth] ( @InputDate    DATETIME )
RETURNS DATETIME
BEGIN

    RETURN CAST(CAST(YEAR(@InputDate) AS VARCHAR(4)) + '/' + 
                CAST(MONTH(@InputDate) AS VARCHAR(2)) + '/01' AS DATETIME)

END
GO
gołąb
źródło
4

To też działa:

    SELECT DATEADD(DAY,(DATEPART(DAY,@mydate)-1)*(-1),@mydate) AS FirstOfMonth
Alan Burstein
źródło
3

Proszę użyć tego

  1. Dla serwera 2012

    DATEFROMPARTS(year('2015-06-30'),month('2015-06-30'),1)
  2. Przed Server 2012

    select  cast(cast(year('2015-06-30') as varchar(4))+'-'+ cast(month('2015-06-30') as varchar(2))+'-01' as smalldatetime)
adnan umar
źródło
3

Pierwszy i ostatni dzień bieżącego miesiąca:

select dateadd(mm, -1,dateadd(dd, +1, eomonth(getdate()))) as FirstDay, 
eomonth(getdate()) as LastDay
Nicolai Koroslev
źródło
2
SELECT @myDate - DAY(@myDate) + 1
PoloSoares
źródło
Naprawdę proste i eleganckie rozwiązanie, ale pamiętaj, że zwraca to również część czasową daty, jeśli jest określona w zmiennej.
kuklei
Nie mogłem tego uruchomić. Poza dodatkowym uchwytem zamknięcia, otrzymuję ten błąd: Operand type clash: date is incompatible with int. Chyba dlatego, że próbujesz skorzystać z -operatora na randce?
Sam
Nie wiem, jak dobry jest pod względem wydajności, ale na pewno działa.
salcoin,
@Sam, masz starcie, ponieważ prosta arytmetyka (+, -) działa na okresach danych, a nie na datach.
darlove
2
----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth
kaub0st3r
źródło
Ale OP szuka pierwszego dnia miesiąca. Ostatniego dnia możesz po prostu użyć EOMONTH () - działa w ten sposób od 2012 roku.
deutschZuid
1

Przyszli pracownicy Google na MySQL wypróbuj to:

select date_sub(ref_date, interval day(ref_date)-1 day) as day1;
Ariel T.
źródło
3
To jest sql-serverpytanie date_subi intervalmysql.
OGHaza,
Dobrze, punkt, zredagowałem odpowiedź. Myślę, że to wciąż dotyczy wątku.
Ariel T
1

Użyłem GETDATE () jako daty do pracy, możesz go zastąpić datą, której potrzebujesz.
Oto jak to działa: Najpierw formatujemy datę w formacie RRRRMMDD ... obcinając, aby zachować tylko 6 znaków z lewej strony, aby zachować tylko część RRRRMM, a następnie dodać „01” jako miesiąc - i voila! masz pierwszy dzień bieżącego miesiąca.

SELECT CAST(CONVERT(VARCHAR(6),GETDATE(),112) +'01' AS DATETIME) AS StartOfMonth

BTW, wydajność jest w tym świetna!

Eli
źródło
1

Jeśli patrzysz na to dzisiaj i używasz programu SQL Server 2012 lub nowszego, masz funkcję EOMONTH, która ułatwia:

SELECT DATEADD(day, 1, EOMONTH(DATEADD(month, -1, GETDATE()))) as firstdateofmonth

Możesz zmienić GETDATE () dowolną zmienną daty, którą chcesz.

Ang Li
źródło
1

Tutaj możemy użyć poniższego zapytania do pierwszej daty miesiąca i ostatniej daty miesiąca.

SELECT DATEADD(DAY,1,EOMONTH(Getdate(),-1)) as 'FD',Cast(Getdate()-1 as Date)
as 'LD'
Pradeep Thakur
źródło
1

Jeśli używasz SQL Server 2012 lub nowszego;

SELECT DATEADD(MONTH, -1, DATEADD(DAY, 1, EOMONTH(GETDATE())))
Lankymart
źródło
1
DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(Getdate(),-2))

-2 zapewni ci pierwszy dzień zeszłego miesiąca. tzn. getdate () to 10/15/18. Twoje wyniki to 9/1/18. Zmień na -1, a Twoje wyniki wyniosą 10/1/18. 0 będzie początkiem następnego miesiąca, 11.01.2018 .. itd. Itd.

lub

DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(@mydate,-1))
Brian Widdoes
źródło
1

Spróbuj wykonać następujące zapytanie:

SELECT DATE_ADD(DATE_ADD(LAST_DAY(CURRENT_DATE-INTERVAL 1 DAY),INTERVAL 1 DAY),INTERVAL -1 MONTH)

divya
źródło
0

wybierz CONVERT (data, DATEADD (dd, - (DATEPART (dd, getdate ()) - 1), getdate ()), 120)

Ta funkcja zapewni część datową daty początkowej miesiąca

Tuszar
źródło
0
SELECT DATEADD (DAY, -1 * (DAY(GETDATE()) - 1), GETDATE())

.................................................. ...................

Jeśli nie chcesz czasu, przekonwertuj go na DATE lub jeśli chcesz ustawić czas na 0:00:00, Konwertuj na DATE, a następnie z powrotem na DATETIME.

SELECT CONVERT (DATETIME,  
CONVERT (DATE, DATEADD (DAY, -1 * (DAY(GETDATE()) - 1),
GETDATE())))

Zmień GETDATE () na żądaną datę

Sayka
źródło
0

Osobiście poleciłem sql poniżej, ponieważ kiedy próbuję użyć funkcji daty w klauzuli warunku, bardzo spowalnia moją szybkość zapytania.

w każdym razie możesz spróbować tego.

select CONCAT(DATEPART(YYYY,@mydate),'-',DATEPART(MM,@mydate),'-01')
Galareta
źródło
0

Nie konkurować z żadnym z wielkich umysłów tutaj, ale prosta sugestia nieco inna niż powyższa zaakceptowana odpowiedź.

select dateadd(day, -(datepart(day,@date)+1,@date)
Wayner
źródło
0

Lubię używać FORMAT, możesz nawet określić czas

SELECT FORMAT(@myDate,'yyyy-MM-01 06:00') first_of_a_month
michal
źródło
0

W Sql Server 2012

 select getdate()-DATEPART(day, getdate())+1

 select DATEADD(Month,1,getdate())-DATEPART(day, getdate())
BornToCode
źródło
0

To zapytanie powinno działać bardzo dobrze na MySQL:

SELECT concat(left(curdate(),7),'-01') 
użytkownik11869348
źródło
0

Dla każdego, kto wciąż szuka odpowiedzi, działa to jak urok i eliminuje wszelkie daty. Znacznik czasu jest opcjonalny, na wypadek gdyby wymagał określenia, ale działa również bez niego.

SELECT left(convert(varchar, getdate(),23),7)+'-01 00:00:00'
chimpSociety
źródło
0

Uzyskaj pierwszą datę i ostatnią datę w dniu, który przekazujemy jako parametr w SQL

     @date DATETIME
    SELECT @date = GETDATE()
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@date)-1),@date),105) AS value,
    'First Day of Current Month' AS name
    UNION
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,@date))),
    DATEADD(mm,1,@date)),105),
    'Last Day of Current Month'
    GO


      **OutPut**

12/01/2019  First Day of Current Month
12/31/2019  Last Day of Current Month
rinku Choudhary
źródło
-3

Oto, jak zrobiłbyś to w MySQL:

  select DATE_FORMAT(NOW(), '%Y-%m-1')
jsarma
źródło
4
Podaj, że nie jest to odpowiedź serwera SQL, ale działa tylko na MySQL.
kuklei
W przypadku programu SQL Server można użyć opcjiSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER,
Nie zachęcaj ludzi do formatowania dat na ciągi, aby zrobić coś, co można i należy wykonać numerycznie. To tak, jakby powiedzieć: „możesz zaokrąglić liczbę w dół do najbliższej 100, formatując ją w łańcuch, podciągając wszystkie poza ostatnimi dwiema cyframi i łącząc na„ 00 ””
Caius Jard