Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL Wählen Sie die letzten 7 Tage aus

Das WHERE Klausel falsch platziert ist, muss sie den Tabellenreferenzen und JOIN-Operationen folgen.

Etwa so:

 FROM tartikel p1 
 JOIN tartikelpict p2 
   ON p1.kArtikel = p2.kArtikel 
  AND p2.nNr = 1
WHERE p1.dErstellt >= DATE(NOW()) - INTERVAL 7 DAY
ORDER BY p1.kArtikel DESC

BEARBEITEN (mehr als drei Jahre später)

Das Obige beantwortet im Wesentlichen die Frage „Ich habe versucht, meiner Abfrage eine WHERE-Klausel hinzuzufügen, und jetzt gibt die Abfrage einen Fehler zurück, wie kann ich ihn beheben?“

Zu einer Frage zum Schreiben einer Bedingung, die einen Datumsbereich von "letzten 7 Tagen" überprüft...

Das hängt wirklich von der Interpretation der Spezifikation ab, was der Datentyp der Spalte in der Tabelle ist (DATE oder DATETIME) und welche Daten verfügbar sind ... was zurückgegeben werden soll.

Zusammenfassend:Der allgemeine Ansatz besteht darin, einen "Start" für den Datums-/Datumszeitbereich und ein "Ende" dieses Bereichs zu identifizieren und in einer Abfrage auf diese zu verweisen. Betrachten wir etwas Einfacheres... alle Zeilen für "gestern".

Wenn unsere Spalte vom Typ DATE ist. Bevor wir einen Ausdruck in eine Abfrage einbauen, können wir ihn in einem einfachen SELECT

testen
 SELECT DATE(NOW()) + INTERVAL -1 DAY 

und überprüfen Sie, ob das zurückgegebene Ergebnis unseren Erwartungen entspricht. Dann können wir denselben Ausdruck in einer WHERE-Klausel verwenden und ihn mit einer DATE-Spalte wie dieser vergleichen:

 WHERE datecol = DATE(NOW()) + INTERVAL -1 DAY

Für eine DATETIME- oder TIMESTAMP-Spalte können wir >= verwenden und < Ungleichheitsvergleiche, um einen Bereich anzugeben

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -1 DAY
   AND datetimecol <  DATE(NOW()) + INTERVAL  0 DAY

Für "letzte 7 Tage" müssen wir wissen, ob das bedeutet, von diesem Punkt an jetzt, 7 Tage zurück ... z. die letzten 7*24 Stunden , einschließlich der Zeitkomponente im Vergleich, ...

 WHERE datetimecol >= NOW() + INTERVAL -7 DAY
   AND datetimecol <  NOW() + INTERVAL  0 DAY

die letzten sieben vollständigen Tage, ohne den heutigen Tag

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -7 DAY
   AND datetimecol <  DATE(NOW()) + INTERVAL  0 DAY

oder vergangene sechs volle Tage plus heute ...

 WHERE datetimecol >= DATE(NOW()) + INTERVAL -6 DAY
   AND datetimecol <  NOW()       + INTERVAL  0 DAY

Ich empfehle, die Ausdrücke auf der rechten Seite in einer SELECT-Anweisung zu testen. Wir können eine benutzerdefinierte Variable anstelle von NOW() zum Testen verwenden, ohne an das gebunden zu sein, was NOW() zurückgibt, sodass wir Grenzen über Woche/Monat hinweg testen können /Jahresgrenzen usw.

SET @clock = '2017-11-17 11:47:47' ;

SELECT DATE(@clock)
     , DATE(@clock) + INTERVAL -7 DAY 
     , @clock + INTERVAL -6 DAY 

Sobald wir Ausdrücke haben, die Werte zurückgeben, die für „Start“ und „Ende“ für unseren speziellen Anwendungsfall funktionieren, was wir mit „letzte 7 Tage“ meinen, können wir diese Ausdrücke in Bereichsvergleichen in der WHERE-Klausel verwenden.

(Einige Entwickler bevorzugen die Verwendung des DATE_ADD und DATE_SUB Funktionen anstelle von + INTERVAL val DAY/HOUR/MINUTE/MONTH/YEAR Syntax.

Und MySQL bietet einige praktische Funktionen für die Arbeit mit den Datentypen DATE, DATETIME und TIMESTAMP ... DATE, LAST_DAY,

Einige Entwickler ziehen es vor, den Anfang und das Ende in anderem Code zu berechnen und Zeichenfolgenliterale in der SQL-Abfrage bereitzustellen, sodass die an die Datenbank gesendete Abfrage

lautet
  WHERE datetimecol >= '2017-11-10 00:00'
    AND datetimecol <  '2017-11-17 00:00'

Und dieser Ansatz funktioniert auch. (Meine Präferenz wäre es, diese String-Literale explizit in DATETIME zu wandeln, entweder mit CAST, CONVERT oder einfach dem + INTERVAL-Trick ...

  WHERE datetimecol >= '2017-11-10 00:00' + INTERVAL 0 SECOND
    AND datetimecol <  '2017-11-17 00:00' + INTERVAL 0 SECOND

Das Obige setzt voraus, dass wir "Daten" in geeigneten DATE-, DATETIME- und / oder TIMESTAMP-Datentypen speichern und sie nicht als Zeichenfolgen in verschiedenen Formaten speichern, z. 'dd/mm/yyyy' , m/d/yyyy , Julianische Daten oder in sporadisch nicht-kanonischen Formaten oder als Anzahl von Sekunden seit dem Beginn der Epoche, müsste diese Antwort viel länger sein.