Wie kann ich den ersten Tag eines Monats in SQL auswählen?


308

Ich muss nur den ersten Tag des Monats einer bestimmten Datums- / Uhrzeitvariablen auswählen.

Ich weiß, dass es ziemlich einfach ist, diese Art von Code zu verwenden:

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

Aber das ist nicht sehr elegant und wahrscheinlich auch nicht sehr schnell.

Gibt es einen besseren Weg, dies zu tun? Ich verwende SQL Server 2008.

Antworten:


604
SELECT DATEADD(month, DATEDIFF(month, 0, @mydate), 0) AS StartOfMonth


63
Es sollte beachtet werden, dass der von Martin Smith erwähnte Fehler "nur" die Leistung beeinträchtigen kann, nicht die Korrektheit.
Olson.dev


34
Falls sich jemand wundert SELECT EOMONTH(@mydate) AS EndOfMonth, erhalten Sie den letzten Tag des Monats.
Hallizh

3
Wie kann ich feststellen, ob der festgestellte Fehler bei der Kardinalitätsschätzung mich betrifft? Es wird 2010 als behoben markiert. Bedeutet dies, dass nur SQL Server 2012 und höher sicher sind, oder ist es möglich, dass ein 2008-Server gepatcht wurde?
Jon

134

Zusätzlich zu all den obigen Antworten wurde ein Weg gefunden, der auf einer in eingeführten Funktion basiert sql 2012

SELECT DATEFROMPARTS(YEAR(@mydate),MONTH(@mydate),1)


14

Das Umwandeln eines Strings (dh "01.05.2009") in datetime ist sicherlich besser lesbar, aber wir haben vor einiger Zeit Code gefunden, der den ersten des Monats zurückgeben würde ...

DECLARE @Date DATETIME
//...
SELECT DATEADD(mm, DATEDIFF(mm,0,@Date), 0)

10

Einfache Abfrage:

SELECT DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0) 
-- Instead of GetDate you can put any date.

6

Es ist wahrscheinlich ziemlich schnell. Warum erstellen Sie es nicht als SQL-Funktion?

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

4

Das funktioniert auch:

    SELECT DATEADD(DAY,(DATEPART(DAY,@mydate)-1)*(-1),@mydate) AS FirstOfMonth

3

Bitte benutzen Sie dies

  1. Für Server 2012

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

    select  cast(cast(year('2015-06-30') as varchar(4))+'-'+ cast(month('2015-06-30') as varchar(2))+'-01' as smalldatetime)

3

Erster und letzter Tag des laufenden Monats:

select dateadd(mm, -1,dateadd(dd, +1, eomonth(getdate()))) as FirstDay, 
eomonth(getdate()) as LastDay

2
SELECT @myDate - DAY(@myDate) + 1

Wirklich einfache und elegante Lösung, aber denken Sie daran, dass dies auch den Zeitanteil des Datums zurückgibt, wenn dies in der Variablen angegeben ist.
Kuklei

Ich konnte das nicht zum Laufen bringen. Neben der zusätzlichen schließenden Klammer erhalte ich folgende Fehlermeldung : Operand type clash: date is incompatible with int. Ich denke, es liegt daran, dass Sie versuchen, den -Operator für ein Datum zu verwenden?
Sam

Ich weiß nicht, wie gut es in Bezug auf die Leistung ist, aber es macht auf jeden Fall den Job.
Salcoin

@Sam, du hast einen Konflikt, weil einfache Arithmetik (+, -) zu Datumszeiten funktioniert, nicht zu Datumsangaben.
Liebling

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

Aber das OP sucht den ersten Tag des Monats. Für den letzten Tag könnte man einfach EOMONTH () verwenden - ist seit 2012 so.
deutschZuid


1

Zukünftige Googler unter MySQL versuchen dies:

select date_sub(ref_date, interval day(ref_date)-1 day) as day1;

3
Dies ist eine sql-serverFrage date_subund intervalsind mysql.
OGHaza

Gut, Punkt, ich habe die Antwort bearbeitet. Ich denke, es ist immer noch relevant für den Thread.
Ariel T

1

Ich habe GETDATE () als Datum für die Arbeit verwendet. Sie können es durch das Datum ersetzen, das Sie benötigen.
So funktioniert das: Zuerst formatieren wir das Datum im Format JJJJMMTT ... und kürzen es, um nur die 6 Zeichen ganz links beizubehalten, um nur den Teil JJJJMM beizubehalten. Dann fügen wir '01' als Monat hinzu - und voila! Sie haben den ersten Tag des aktuellen Monats.

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

Übrigens, die Leistung ist großartig!


1

Wenn Sie sich das heute ansehen und SQL Server 2012 oder höher verwenden, haben Sie die EOMONTH-Funktion, die die Dinge einfacher macht:

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

Sie können GETDATE () mit einer beliebigen Datumsvariablen ändern.


1

Hier können wir die folgende Abfrage zum ersten Datum des Monats und zum letzten Datum des Monats verwenden.

SELECT DATEADD(DAY,1,EOMONTH(Getdate(),-1)) as 'FD',Cast(Getdate()-1 as Date)
as 'LD'

1

Bei Verwendung von SQL Server 2012 oder höher;

SELECT DATEADD(MONTH, -1, DATEADD(DAY, 1, EOMONTH(GETDATE())))

1
DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(Getdate(),-2))

Mit der -2 erhalten Sie den ersten Tag des letzten Monats. dh getdate () ist der 15.10.18. Ihre Ergebnisse wären 9/1/18. Wechseln Sie zu -1 und Ihre Ergebnisse wären 10/1/18. 0 wäre der Anfang des nächsten Monats, 11/1/2018 .. etc etc.

oder

DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(@mydate,-1))

1

Versuchen Sie, die folgende Abfrage auszuführen:

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


0

Wählen Sie CONVERT (Datum, DATEADD (dd, - (DATEPART (dd, getdate ()) - 1), getdate ()), 120).

Diese Funktion gibt Ihnen das Datum als Teil des Startdatums des Monats an


0
SELECT DATEADD (DAY, -1 * (DAY(GETDATE()) - 1), GETDATE())

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

Wenn Sie die Zeit nicht möchten, konvertieren Sie sie in DATE oder wenn Sie die Zeit auf 0:00:00 einstellen möchten, konvertieren Sie sie in DATE und dann zurück in DATETIME.

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

Ändern Sie GETDATE () auf das gewünschte Datum


0

Ich persönlich habe empfohlen, dass die unten stehende SQL, weil ich versuche, die Datumsfunktion in der Bedingungsklausel zu verwenden, meine Abfragegeschwindigkeit sehr verlangsamt.

Fühlen Sie sich trotzdem frei, dies zu versuchen.

select CONCAT(DATEPART(YYYY,@mydate),'-',DATEPART(MM,@mydate),'-01')

0

Nicht mit einem der großen Köpfe hier zu konkurrieren, sondern ein einfacher Vorschlag, der etwas anders ist als die oben akzeptierte Antwort.

select dateadd(day, -(datepart(day,@date)+1,@date)

0

Ich benutze gerne FORMAT, man kann sogar eine Zeit angeben

SELECT FORMAT(@myDate,'yyyy-MM-01 06:00') first_of_a_month

0

In SQL Server 2012

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

 select DATEADD(Month,1,getdate())-DATEPART(day, getdate())

0

Diese Abfrage sollte unter MySQL sehr gut funktionieren:

SELECT concat(left(curdate(),7),'-01') 

0

Für alle, die noch nach einer Antwort suchen, funktioniert dies wie ein Zauber und beseitigt alle Datenköpfe. Der Zeitstempel ist optional, falls er angegeben werden muss, funktioniert aber auch ohne.

SELECT left(convert(varchar, getdate(),23),7)+'-01 00:00:00'

0

Holen Sie sich das erste und das letzte Datum in dem Datum, das wir als Parameter in SQL übergeben

     @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

-3

So würden Sie es in MySQL machen:

  select DATE_FORMAT(NOW(), '%Y-%m-1')

4
Bitte geben Sie an, dass dies keine SQL Server-Antwort ist, sondern nur unter MySQL funktioniert.
Kuklei

Für SQL Server können Sie verwendenSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

Ermutigen Sie die Benutzer nicht, Daten in Zeichenfolgen zu formatieren, nur um etwas zu tun, das numerisch erfolgen kann und sollte. Es ist so, als würde man sagen "Sie können eine Zahl auf die nächsten 100 abrunden, indem Sie sie in eine Zeichenfolge formatieren, alle bis auf die letzten beiden Ziffern mit einer Teilzeichenfolge versehen und eine '00' verketten"
Caius Jard
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.