Abfrage, um alle Zeilen des Vormonats abzurufen

86

Ich muss alle Zeilen in meiner Datenbank auswählen, die im letzten Monat erstellt wurden.

Wenn der aktuelle Monat beispielsweise Januar ist, möchte ich alle Zeilen zurückgeben, die im Dezember erstellt wurden. Wenn der Monat Februar ist, möchte ich alle Zeilen zurückgeben, die im Januar erstellt wurden. Ich habe eine date_createdSpalte in meiner Datenbank, in der das in diesem Format erstellte Datum aufgeführt ist : 2007-06-05 14:50:17.

lewisqic
quelle

Antworten:

192
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Hobodave
quelle
66
SELECT * FROM table WHERE date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir
10
@GhazanfarMir Ihre Anfrage stimmt nicht ganz mit der Frage überein, wohingegen die obige Antwort dies tut. Ihre gibt die Zeilen zwischen diesem Tag im letzten Monat bis gestern zurück.
Matt Passell
@MattPassell Es tut mir leid, aber es betweenschließt die Grenzen ein. Es wird auch das aktuelle Datum enthalten. Warum / wie wird es auf gestern beschränkt sein? Bitte näher erläutern?
Ghazanfar Mir
4
Ich verstehe, was du meinst. Ja, du hast Recht. Meine Frage ist nicht das, was OP wollte. Ich habe die Frage falsch verstanden
Ghazanfar Mir
Was ist, wenn current_datees nicht heute ist, sondern ein zufälliges Datum vom Kunden angegeben?
Dios231
22

Hier ist eine andere Alternative. Angenommen, Sie haben ein indiziertes Feld DATEoder ein Typfeld DATETIME, sollte dies den Index verwenden, da die formatierten Daten vor der Verwendung des Index typkonvertiert werden. Sie sollten dann eine rangeAbfrage anstelle einer indexAbfrage sehen, wenn Sie mit EXPLAIN angezeigt werden .

SELECT
    * 
FROM
    table
WHERE 
    date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' ) 
AND
    date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
Martin Clayton
quelle
+1. Viel indexfreundlicher. Sie können auch ein STR_TO_DATEum das werfen, DATE_FORMATdamit es sich immer um Datumsobjekte handelt.
Leigh
13

Wenn es keine zukünftigen Daten gibt ...

SELECT * 
FROM   table_name 
WHERE  date_created > (NOW() - INTERVAL 1 MONTH);

Geprüft.

ekerner
quelle
3
Ich denke, sie suchten etwas anderes. dh Alle Datensätze vom letzten Monat (dh 1. Oktober - 31. Oktober 2012, 23:59:59 Uhr). Die obige Abfrage würde die letzten ca. 30 Tage ab dem heutigen Datum und der heutigen Uhrzeit zurückgeben .
Leigh
13

Alternativ zur Antwort von Hobodave

SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)

Sie könnten dasselbe mit EXTRACT erreichen, indem Sie YEAR_MONTH als Einheit verwenden, sodass Sie das UND nicht benötigen würden, wie folgt:

SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)
SMTF
quelle
Dies funktioniert monatelang hervorragend, aber leider gibt es kein YEAR_WEEK zeitliches Intervall , sodass Sie auf die Antwort von hobodave zurückgreifen müssen, wenn Sie Wochen statt Monate benötigen.
Danny Beckett
8
SELECT *
FROM  yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')

Dies sollte alle Datensätze des vorherigen Kalendermonats zurückgeben, im Gegensatz zu den Datensätzen der letzten 30 oder 31 Tage.

Gregg
quelle
Ich habe vergessen zu erwähnen ... dies sollte alle Datensätze des vorherigen Kalendermonats zurückgeben, im Gegensatz zu den Datensätzen der letzten 30 oder 31 Tage.
Gregg
Meiner Meinung nach sollte dies die akzeptierte Antwort sein, da sie einfacher als die akzeptierte Antwort ist und dennoch das gleiche Ergebnis liefert
Grant
3

Obwohl die Antwort auf diese Frage bereits ausgewählt wurde, glaube ich, dass die einfachste Abfrage sein wird

SELECT * 
FROM table 
WHERE 
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
Ghazanfar Mir
quelle
2
Nein, nicht ganz. Siehe meine Antwort auf Ihren Kommentar zu der Antwort von @hobodave
Matt Passell
@MattPassell Sie haben Recht, ich habe die Frage falsch verstanden. Ich habe den Punkt übersehen, dass das Ergebnis nur auf Aufzeichnungen NUR vom letzten Monat beschränkt sein sollte.
Ghazanfar Mir
2
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY) 
  AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY) 

Dies hat bei mir funktioniert (Wählt alle Datensätze aus, die im letzten Monat erstellt wurden, unabhängig davon, an welchem ​​Tag Sie die Abfrage in diesem Monat ausführen.)

Giles
quelle
1

select fields FROM table WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');

Dieser kann einen Index nutzen, wenn Ihr date_created indiziert ist, da er keine Transformationsfunktion auf den Feldwert anwendet.

ggiroux
quelle
@ggiroux - Es muss jedoch das Datum in einen Zeichentyp konvertieren, bevor LIKE angewendet wird.
Martin Clayton
Ja, aber immer noch eine Verbesserung gegenüber der ausgewählten Antwort IMHO (IFF date_created ist indiziert)
ggiroux
1

Hier ist die Abfrage, um die Aufzeichnungen des letzten Monats abzurufen:

SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND 
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )

Grüße - saqib

Saqib Jahangir Pakistan
quelle
Haben Sie versucht, diese Abfrage auszuführen? Soweit ich sehe, würde es nicht alle Daten aus den Vormonaten auswählen (wie in: Rückgabedaten von Januar über den gesamten Februar), sondern Daten aus einem Bereich zurückgeben, der am selben Tag vor einem Monat beginnt
Nico Haase,
-1
SELECT *  FROM table  
WHERE  YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Sid Busa
quelle
Haben Sie versucht, diese Abfrage auszuführen? Soweit ich sehe, würde es nicht alle Daten aus den Vormonaten auswählen (wie in: Rückgabedaten von Januar über den gesamten Februar), sondern Daten aus einem Bereich zurückgeben, der am selben Tag vor einem Monat beginnt
Nico Haase,
Ich hatte einige Änderungen vorgenommen, überprüfen Sie jetzt, ob es funktioniert oder nicht
Sid Busa