Wie subtrahiere ich 30 Tage von der aktuellen Datumszeit in MySQL?

194

Wie subtrahiere ich 30 Tage von der aktuellen Datums- / Uhrzeitangabe in MySQL?

SELECT * FROM table
WHERE exec_datetime BETWEEN DATEDIFF(NOW() - 30 days) AND NOW();
user784637
quelle

Antworten:

127

Für alle, die nicht verwenden möchten DATE_SUB, verwenden Sie CURRENT_DATE:

SELECT CURRENT_DATE - INTERVAL 30 DAY
Doug Fir
quelle
2
Ich würde diese +10 geben, wenn ich könnte. In SQL sollte alles um Lesbarkeit gehen, und dies ist der am besten lesbare Weg, dies zu tun.
Colin 't Hart
9
Lesbarer, aber anderes Ergebnis als bei Verwendung NOW() - INTERVAL 30 DAY. Da in der Frage "30 Tage vom aktuellen Datum abziehen " erwähnt wird, ist dies möglicherweise nicht das, was das OP wünscht.
Ypercubeᵀᴹ
2
@ ypercubeᵀᴹ dann current_timestampanstelle voncurrent_date
isapir
21

Lassen Sie uns nicht verwenden, NOW()da Sie das Zwischenspeichern oder Optimieren von Abfragen verlieren, da die Abfrage jedes Mal anders ist. Siehe die Liste der Funktionen, die Sie nicht verwenden sollten, in der MySQL-Dokumentation .

Nehmen wir im folgenden Code an, dass diese Tabelle mit der Zeit wächst. Es werden neue Inhalte hinzugefügt, und Sie möchten nur die Inhalte der letzten 30 Tage anzeigen. Dies ist der häufigste Fall.

Beachten Sie, dass das Datum als Zeichenfolge hinzugefügt wurde. Es ist besser, das Datum auf diese Weise aus Ihrem Aufrufcode hinzuzufügen, als die NOW()Funktion zu verwenden, da sie das Caching beendet.

SELECT * FROM table WHERE exec_datetime >= DATE_SUB('2012-06-12', INTERVAL 30 DAY);

Sie können es verwenden, BETWEENwenn Sie wirklich nur Dinge von dieser Sekunde bis 30 Tage vor dieser Sekunde wollen, aber dies ist meiner Erfahrung nach kein häufiger Anwendungsfall, daher hoffe ich, dass die vereinfachte Abfrage Ihnen gute Dienste leisten kann.

Joseph Lust
quelle
3
Sie haben also vorgeschlagen, keine Verwendung zu verwenden NOW()und sie dennoch in Ihrer Antwort zu verwenden. o_O PS: Ihre Anfrage würde ein anderes Ergebnis zurückgeben, nicht das, was OP wahrscheinlich will
zerkms
@zerkms Wie würde diese Abfrage eine andere Ergebnismenge als Ihre Abfrage erzeugen?
user784637
2
@ user784637: ähm, BETWEENund >=sind verschiedene Operatoren, weißt du? Meine Abfrage begrenzt die Ergebnismenge 30 days ago AND todaydafür everything after 30 days ago. Die tomorrowDatensätze stimmen also nicht mit meinen und Ihrer ursprünglichen Abfrage überein, sondern mit dieser Antwort
zerkms
Ok, mein schlechtes. Typischerweise befinden sich solche Abfragen in Live-Tabellen, die mit der Zeit wachsen. Deshalb habe ich das dazwischen fallen lassen. Ich habe meine Antwort oben klargestellt.
Joseph Lust
@JosephLust, Um Leistungsprobleme zu lösen, verwenden Sie stattdessen meine Lösung .
Pacerier
17

MySQL subtrahiert Tage von jetzt an:

select now(), now() - interval 1 day

Drucke:

2014-10-08 09:00:56     2014-10-07 09:00:56

Andere Argumente der Intervall Temporal Expression Unit:

https://dev.mysql.com/doc/refman/5.5/en/expressions.html#temporal-intervals

select now() - interval 1 microsecond 
select now() - interval 1 second 
select now() - interval 1 minute 
select now() - interval 1 hour 
select now() - interval 1 day 
select now() - interval 1 week 
select now() - interval 1 month 
select now() - interval 1 year 
Eric Leschinski
quelle
16

Sie können auch verwenden

select CURDATE()-INTERVAL 30 DAY
Noby Nirmal
quelle
1
SELECT date_format(current_date - INTERVAL 50 DAY,'%d-%b-%Y')

Sie können mithilfe des Datumsformats in SQL formatieren.

Varaj Vignesh
quelle
0

ein anderer Weg

SELECT COUNT(*) FROM tbl_debug WHERE TO_DAYS(`when`) < TO_DAYS(NOW())-30 ;
zzapper
quelle
0

Wenn Sie nur das Datum und nicht die Uhrzeit benötigen, verwenden Sie:

select*from table where exec_datetime
between subdate(curdate(), 30)and curdate();

Da die curdate()Zeitkomponente weggelassen wird, ist sie möglicherweise schneller now()und "semantisch korrekter", wenn Sie nur am Datum interessiert sind.

Außerdem ist subdate()die 2-Arity-Überlastung möglicherweise schneller als die Verwendung interval. intervalist für Fälle gedacht, in denen Sie eine Nicht-Tageskomponente benötigen.

Pacerier
quelle
11
Sie behaupten also, das subdate(curdate(), 30)sei schneller als CURRENT_DATE - INTERVAL 30 DAY? Hast du Beweise? Und wie schnell wäre das? Ein paar Mikrosekunden?
Ypercubeᵀᴹ
2
Ich habe keine Ahnung. Ich kann meine eigenen Kommentare sicherlich nicht positiv bewerten. Über die "möglicherweise" schnellere Behauptung sehe ich immer noch keinen Beweis, weder entscheidend noch umständlich. Und selbst wenn es etwas schneller ist, würde der Zustand einmal ausgewertet. Wenn Sie die Abfrage nicht millionenfach pro Minute ausführen, spielt der Unterschied keine Rolle.
Ypercubeᵀᴹ
2
Ich vermute subdate, dass es Ihrer Meinung nach wahrscheinlich schneller durch seine "2-Arity-Überlastung" erklärt wird, potenziell schneller zu sein, aber bitte verzeihen Sie mir, wenn dies eine dumme Frage ist, was bedeuten diese Wörter (in Bezug auf eine Funktion) )? Was ist insbesondere "2-Arität"?
Andriy M
1
Auch was den Wortlaut der Frage angeht , curdate()könnte dies tatsächlich die falsche Wahl sein, da das OP anscheinend "30 Tage von der aktuellen Datumszeit abziehen " wollte (Hervorhebung von mir).
Andriy M
1
@AndriyM, Nun, da dieser Thread 50.000 Aufrufe erhält, lasse ich die Antwort hier für Leute, die nur an der Zeitkomponente interessiert sind. Und in Bezug auf "Arität" bezieht es sich auf die Anzahl der Argumente . Ja, das ist richtig. Bei gleichen Bedingungen ist eine 2-Arity-Funktion möglicherweise schneller als eine 3-Arity-Funktion. Dies gilt so lange, bis neue Informationen zur Platte hinzugefügt werden.
Pacerier