web-dev-qa-db-ja.com

日時列から日付を選択する方法

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

ただし、これは空の結果セットを返します。助言がありますか?

202
mysqllearner

MySQLの DATE() 関数を使うことができます。

WHERE DATE(datetime) = '2009-10-20'

あなたもこれを試すことができます:

WHERE datetime LIKE '2009-10-20%'

LIKEを使用することによるパフォーマンスへの影響については、 この回答 を参照してください。

378
Priyank Bolia

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を使ってプロジェクトの古いコードを書き換えているときにこれを見つけました。

81
IvanRF

日時をY-M-D部分にフォーマットできます。

DATE_FORMAT(datetime, '%Y-%m-%d')
23
Prusprus

ページ上のすべての答えは望ましい結果を返しますが、それらはすべてパフォーマンスの問題を抱えています。 計算はテーブル内のすべての行に対して実行する必要があるため、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秒未満のタイムスタンプ精度などのコーナーケースもサポートしています。また、それは将来の証拠です。

10
dotancohen

ここにすべてのフォーマットがあります

テーブルdatetimedata値を含む列だとします。

+--------------------+
| 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 |
+----------------------+
7
Siraj

あなたが使用することができます:

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))
4

日付関数を使用するためのシンプルで最良の方法

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

OR

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'