2009-10-20 10:00:00のような値を持つタイプ "datetime"の列があります。
Datetimeから日付を抽出して、以下のようなクエリを書きたいと思います。
SELECT * FROM
data
WHERE datetime = '2009-10-20'
ORDER BY datetime DESC
次のようにするのが最善の方法ですか?
SELECT * FROM
data
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC
ただし、これは空の結果セットを返します。助言がありますか?
WHERE DATE(datetime) = '2009-10-20'
を使用すると、パフォーマンスの問題が発生します。述べたように ここ :
DATE()
を計算します。インデックスの使用を許可するBETWEEN
または>
、<
、=
演算子を使用します。
SELECT * FROM data
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'
更新:の影響では、インデックス付き列の演算子の代わりにLIKE
を使用していますは、高いです。以下は、1,176,000行のテーブルに対するいくつかのテスト結果です。
datetime LIKE '2009-10-20%'
=> 2931msを使用datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'
=> 168msを使用同じクエリで2回目の呼び出しを行う場合、その差はさらに大きくなります。2984ミリ秒と7ミリ秒(はい、わずか7ミリ秒です)。 Hibernateを使ってプロジェクトの古いコードを書き換えているときにこれを見つけました。
日時をY-M-D部分にフォーマットできます。
DATE_FORMAT(datetime, '%Y-%m-%d')
ページ上のすべての答えは望ましい結果を返しますが、それらはすべてパフォーマンスの問題を抱えています。 計算はテーブル内のすべての行に対して実行する必要があるため、WHERE
句内のフィールドに対して計算を実行しないでください(DATE()
計算を含む)。
BETWEEN ... AND
コンストラクトは両方の境界条件を含み、終了日に23:59:59構文を指定する必要があります。それ自体には他の問題があります(マイクロ秒トランザクション。MySQLは2009年に質問されたときにサポートされません).
特定の日にMySQLのtimestamp
フィールドを問い合わせる正しい方法は、希望する日付に対してGreater-Than-Equalsを、次の日にLess-Thanを時間を指定せずにチェックすることです。
WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'
これは、最もパフォーマンスが速く、メモリ使用量が最も少なく、リソースをあまり必要としない方法です。さらに、MySQLのすべての機能と1秒未満のタイムスタンプ精度などのコーナーケースもサポートしています。また、それは将来の証拠です。
テーブルdatetime
のdata
値を含む列だとします。
+--------------------+
| date_created |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+
mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02 |
+--------------------+
mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
| 2018 |
+--------------------+
mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
| 6 |
+---------------------+
mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
| 2 |
+-------------------+
mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
| 15 |
+--------------------+
mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
| 50 |
+----------------------+
mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
| 31 |
+----------------------+
あなたが使用することができます:
DATEDIFF ( day , startdate , enddate ) = 0
または
DATEPART( day, startdate ) = DATEPART(day, enddate)
AND
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)
または
CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))
日付関数を使用するためのシンプルで最良の方法
例
SELECT * FROM
data
WHERE date(datetime) = '2009-10-20'
OR
SELECT * FROM
data
WHERE date(datetime ) >= '2009-10-20' && date(datetime ) <= '2009-10-20'