MySQLの現在の日時から30日を引く方法は?


194

MySQLの現在の日時から30日を差し引くにはどうすればよいですか?

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

回答:



127

使用したくない人にはDATE_SUB、次を使用してCURRENT_DATEください:

SELECT CURRENT_DATE - INTERVAL 30 DAY

2
できれば+10をあげます。SQLはすべて読みやすさを重視する必要があり、これが最も読みやすい方法です。
Colin 't Hart

9
を使用しNOW() - INTERVAL 30 DAYた場合よりも読みやすくなりますが、結果は異なります。質問には「現在の日時から30日を引く」と記載されているため、OPが望んでいない場合があります。
ypercubeᵀᴹ

2
@ypercubeᵀᴹのcurrent_timestamp代わりに使用current_date
isapir

21

NOW()クエリは毎回異なるため、クエリのキャッシュや最適化が失われるため、使用しないでください。MySQLのドキュメントで、使用してはいけない関数のリストを参照してください。

以下のコードでは、このテーブルが時間とともに大きくなっていると仮定します。新しいコンテンツが追加され、過去30日間のコンテンツのみを表示したいとします。これは最も一般的なケースです。

日付は文字列として追加されていることに注意してください。NOW()関数を使用してキャッシュを強制終了するよりも、呼び出しコードからこの方法で日付を追加することをお勧めします。

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

あなたは使用することができBETWEENますが、実際には非常に二本の前に非常秒30日間に、このからものをしたい場合は、私は簡略化されたクエリがうまくあなたを提供することを願っているが、私の経験では一般的なユースケースではありません。


3
だから、あなたは役に立たないことを提案しNOW()、それでもあなたの答えでそれを使います。o_O PS:クエリは、OPが望んでいるものではなく、別の結果を返します
zerkms

@zerkmsこのクエリは、クエリとは異なる結果セットをどのように生成しますか?
user784637

2
@ user784637:オム、BETWEENおよび>=異なる演算子である、あなたは知っていますか?私のクエリは30 days ago AND today、thisの結果セットを制限していますeverything after 30 days ago。したがって、tomorrowレコードは私のものと元のクエリでは一致しませんが、この回答では一致します
zerkms '26年

わかりました。通常、このようなクエリは、時間とともに成長するライブテーブルにあります。だから私はその間に落とした。上記で私の答えを明確にしました。
ジョセフ・ラスト

@JosephLust、パフォーマンスの問題を解決するには代わりに私のソリューションを使用してください
Pacerier、2015

17

MySQLは今から日数を引きます:

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

プリント:

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

その他の時間間隔式の単位引数:

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 



0

別の方法

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

0

日付だけが必要で時間は必要ない場合:

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

curdate()時間コンポーネントを省略しているため、日付のみに関心がある場合の方が、「意味的に正しい」よりも高速で、「意味的に正しい」可能性now()があります。

また、subdate()の2値のオーバーロードは、を使用するよりも潜在的に高速ですintervalinterval曜日以外のコンポーネントが必要な場合のためのものです。


11
それで、あなたはそれsubdate(curdate(), 30)がよりも速いと主張していCURRENT_DATE - INTERVAL 30 DAYますか?証拠はありますか?そして、それはどれくらい速いでしょうか?数マイクロ秒?
ypercubeᵀᴹ

2
何も思いつきません。私は確かに自分のコメントに賛成することはできません。「潜在的に」より速い主張について、私はまだ証拠、決定的、または状況的なものを見ていません。そして、多少速くても、条件は一度評価されます。1分あたり数百万回クエリを実行しない限り、違いは問題になりません。
ypercubeᵀᴹ

2
subdate潜在的に高速であることがおそらく「2アリティオーバーロード」によって何らかの形で説明されていると思いますが、これが愚かな質問である場合は、それらの単語の意味(関数に関して) )?特に「2アリティ」とは?
Andriy M

1
また、curdate()OPは「現在の日時から30日を差し引く」ように見えたため(強調事項)、質問の文言に関しては、実際には間違った選択である可能性があります。
Andriy M

1
@AndriyMさん、このスレッドは5万回のビューを取得しているので、時間コンポーネントのみに関心がある人のためにここで答えを残します。「アリティ」については、引数の数を指します。はい、それは正しいです。すべてが等しいので、2つのアリティ関数は3つのアリティ関数よりも潜在的に高速です。これは、新しい情報がプレートに追加されるまで当てはまります。
Pacerier、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.