2016-06-20 19 views
1

Ich muss SQL für Daten abfragen, die in ein Datum des letzten Monats fallen. Ich dachte, ich würde die richtige Abfragelogik verwenden, aber ich bekomme keine Ergebnisse und weiß, dass es Ergebnisse gibt. Der Code-Snippet ist dies:SQL Query Subtrahieren 1 Monat

MONTH(n.JOIN_DATE) = DATEADD(month, - 1, GETDATE()) 

Dies wird mir keine Ergebnisse geben, und ich brauche jemanden zu bekommen, der ein Beitrittsdatum des letzten Monats hat. Was vermisse ich?

+1

Können Sie Ihre vollständige Abfrage anzeigen? –

+0

Auch einige Beispieldaten wären nett. –

+4

'MONTH()' gibt eine Monatszahl zurück. 'DATEADD()' gibt ein Datum zurück. Ein Monat wird niemals einem Datum gleichkommen. –

Antwort

1

MONTH(n.JOIN_DATE) gibt nur den numerischen Wert des Monats zurück (z. B. 11 oder 5).

DATEADD(MONTH, -1, GETDATE()) wird einfach einen Monat vom aktuellen Datum subtrahieren. Es ist immer noch in einem Format.

Sie können gesucht werden:

MONTH(n.JOIN_DATE) = MONTH(DATEADD(MONTH, -1, GETDATE())) 
3

Mit dieser:

MONTH(n.JOIN_DATE) = MONTH(DATEADD(month, - 1, GETDATE())) 

Sie müssen Äpfel mit Äpfeln vergleichen, so auf beiden Seiten der Gleichung den numerischen Monat vergleichen.

Massiver Kredit an @PaulL, um das herauszufinden, bevor ich es getan habe.

Update:

Wie @DasBlinkenLight und Matt darauf hingewiesen, nur von Monat zu vergleichen lässt die Tür offen für mehrere Jahre zurückgeführt werden. Eine mögliche Lösung wäre, auch die Jahre zu vergleichen, z.

WHERE MONTH(n.JOIN_DATE) = MONTH(DATEADD(month, - 1, GETDATE())) AND 
     YEAR(n.JOIN_DATE) = YEAR(DATEADD(month, - 1, GETDATE())) 
+0

Wenn mehr als 1 Jahr im Datensatz vorhanden ist, werden Ergebnisse aus mehreren Jahren zurückgegeben. Wenn Sie auch AND YEAR (n.JOIN_DATE) = YEAR (DATEADD (Jahr, -1, GETDATE()) hinzufügen, wird dieses Problem gelöst. – Matt

1

MONTH(...) erzeugt eine Monatsnummer. Sie sollten es nicht mit dem von DATEADD zurückgegebenen Ergebnis vergleichen, das eigentlich ein Datum ist.

Wenn Sie alle suchen, die vor weniger als einem Monat beigetreten ist, können Sie es wie folgt tun: nicht nur den Monat

WHERE DATEADD(month, 1, n.JOIN_DATE) > GETDATE() 

Dies auch das Jahr und der Tag berücksichtigt.

Wenn Sie alle suchen, das im letzten Monat verbunden, egal an welchem ​​Tag, können Sie eine komplexere Bedingung verwenden:

WHERE MONTH(DATEADD(month, -1, GETDATE()) = MONTH(n.JOIN_DATE) 
    AND YEAR (DATEADD(month, -1, GETDATE()) = YEAR (n.JOIN_DATE) 

Die zweite Bedingung ist notwendig Verwirrung zwischen den Mitgliedern im letzten Monat Beitritt zu vermeiden und Mitglieder, die vor einem oder mehreren Jahren im selben Monat beitreten.

-2

Die Antwort auf diese Antwort ist korrekt. Aber im Lichte der Best Practice, die Ihre Abfrage auf diese Weise schreibt, wird sie weniger SARGABLE, wodurch sie Indizes ignoriert, wenn Sie eine haben. Es könnte besser sein, es als

WHERE n.JOIN_DATE between DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) 

basierend auf dem Kommentar unten zu schreiben Ich habe die Abfrage geändert. Ich denke, ich habe die Frage nicht gründlich gelesen.

+0

Wenn ich das heute laufen würde, 2016-06-20, würde es nicht 2016- zurückkehren 05-02, was es sollte, würde aber 2016-06-03 zurückgeben, was es nicht tun sollte.Getowned entsprechend –

+0

Zurück zu Ihrer früheren Version DATEADD (Monat, -1, GETDATE()) UND GETDATE() einer gab den richtigen Datumsbereich von 5/20 bis 6/20 zurück.Dieser gibt 6/1 bis 5/31 23: 59: 59.000 zurück, was sowohl in der falschen Reihenfolge als auch nicht in den richtigen Daten ist.Ich weiß nicht was @ DanBracuk tippte, um seine Ergebnisse zu erhalten – Matt

+0

Die Frage sagte, er wollte irgendwann, dass im letzten Monat fällt, das ist die 5/20 Bereich ich vermute oder habe ich das falsch interpretiert? – damola

1
MONTH(n.JOIN_DATE) returns a numeric which indicate the month in date m.JOIN_DATE 
DATEADD(month, - 1, GETDATE()) returns a date which indicate date in last month. 
So, you can use this instead : 
MONTH(n.JOIN_DATE)= MONTH(DATEADD(month, - 1, GETDATE())) 
OR 
n.JOIN_DATE = DATEADD(month, - 1, GETDATE()) 
+0

Sie benötigen eine zwischen oder größer als weniger als alle seine Ergebnisse nicht nur die einen Tag zu bekommen – Matt

+0

Auch das wird nicht funktionieren, wenn es eine Zeitkomponente auf seinen Spalten ist – Matt

0
SELECT 
    DATEFROMPARTS(YEAR(DATEADD(month,-1,GETDATE())),MONTH(DATEADD(month,-1,GETDATE())),1) AS StartOfLastMonth 
    ,DATEADD(day,-1,(DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),1))) AS EndOfLastMonthAsDate 
    ,DATEADD(day,-3,CAST(DATEFROMPARTS(YEAR(GETDATE()),MONTH(GETDATE()),1) AS DATETIME)) AS EndOfLastMonthMidngith 
    ,CAST(DATEADD(month,-1,GETDATE()) AS DATE) AS OneMonthAgoStrartOfDay 
    ,CAST(GETDATE() AS DATE) AS StartOfToday 
    ,DATEADD(MS,-3,CAST(CAST(GETDATE() AS DATE) AS DATETIME)) AS MidnightLastNight 

Gut Da die Menschen haben auf jeden Fall illustriert es viele verschiedene Antworten auf Ihre Fragen sind, und alle sind auf ähnliche Prämisse gebaut. mit DATEADD() mit einer negativen Zahl, um einen Monat zurückzugehen. Oder um Monat und Jahr zu vergleichen, um zu sehen, ob sie gleich sind. Die erste wurde auf 1 Monat bis heute und die letzte auf letzten Monat ausgerichtet.

Alle bisherigen Antworten, erwarten @DasBlinkenLight und @TimBiegeleisen, berücksichtigen TIME Komponente Ihrer Spalte und die GETDATE() Funktion nicht, wenn Sie eine haben. Wenn Ihre Spalte ist, müssen Sie dies berücksichtigen. Die obige SELECT Abfrage, die Sie mit einigen Möglichkeiten bewaffnet, um zu verschiedenen Daten zu gelangen, die ich vermute, wird Ihren Bedürfnissen entsprechen.

Soweit mit BETWEEN mit Daten verwenden, seien Sie vorsichtig! Weil die Werte, die du eingibst, inklusive sind, also wenn du GETDATE() auf die rechte Seite der zwischen-Anweisung legst, wirst du auch die heutigen Ergebnisse erhalten, aber du könntest UP TO bis heute wirklich wollen. In diesem Fall solltest du dein Argument auf der rechten Seite ändern. Auch bin ich nicht sicher über Oracle, MySQL, etc., aber Micrsofot SQL-Server ist genau auf .003 Millisekunden. Also, wenn Sie wirklich auf Mitternacht eines Datums schauen möchten, sollten Sie sich 23:59:59.997 ansehen, weil .998 und .999 auf den nächsten Tag runden werden.

Auch zur weiteren Vereinfachung, wenn Sie nicht wollen, Zeit Komponenten können Sie auch Ihre Spalte zu DATE und es fällt im Wesentlichen die Zeit und die BETWEEN, weil ein wenig auch klar, z. CAST(n.JOIN_DATE AS DATE)

Es gibt definitiv andere Fragen zu diesem Thema auf Stackoverflow ermutige ich Sie zu recherchieren.

-1

Ich wusste, das war ein einfaches und mir fehlte etwas. Mein Code war falsch, basierend auf den vielen Antworten, die ich diesbezüglich erhielt und ich habe Äpfel mit Orangen und nicht Äpfel mit Äpfeln verglichen. Sobald ich die Month() um die dateadd Funktion hinzugefügt hatte, funktionierte es.

+0

Vorsicht, wenn Ihre Daten mehrere Jahre enthalten.Wenn Sie den gesamten letzten Monat möchten, müssen Sie sowohl das JAHR des letzten Monats mit dem JAHR Ihres n.JOIN_DATEs als auch den Monat vergleichen. Andernfalls, wenn Ihre Daten mehrere Jahre haben, erhalten Sie diesen Monat für jedes Jahr in Ihren Ergebnissen – Matt