web-dev-qa-db-ja.com

Mysql日付関数が以下の期間機能していません

2012-12-28以下のすべてのレコードを取得する必要があります。これに以下のクエリを使用しました。booking_timeはDATETIMEフィールドであり、2012-12-28未満のレコードがありますが、ゼロ行を返します。誰もがアイデアを持っていますか?

SELECT * FROM ctx_bookings WHERE DATE(booking_time)<=2012-12-28 ORDER BY id ASC

提出された表

+---------------------+
| booking_time        |
+---------------------+
| 2012-12-20 03:10:09 |
| 2012-12-25 02:10:04 |
+---------------------+

なぜこれが起こっているのか誰でも知ってください?

16
Gihan Dilusha

値を一重引用符でラップすると、確実に機能します

SELECT * 
FROM ctx_bookings 
WHERE DATE(booking_time) <= '2012-12-28' 
ORDER BY id ASC
44
John Woo

Date and Time Literals で文書化されているとおり:

MySQLは、次の形式の DATE 値を認識します。

  • _'YYYY-MM-DD'_または_'YY-MM-DD'_形式の文字列として。 「リラックスした」構文を使用できます。日付部分間の区切り文字として、句読点を使用できます。たとえば、_'2012-12-31'_、_'2012/12/31'_、_'2012^12^31'_、および_'2012@12@31'_は同等です。

  • _'YYYYMMDD'_または_'YYMMDD'_形式の区切り文字のない文字列。ただし、文字列が日付として意味がある場合。たとえば、_'20070523'_および_'070523'_は_'2007-05-23'_として解釈されますが、_'071332'_は無効であり(意味のない月と日の部分があります)、_'0000-00-00'_になります。

  • YYYYMMDDまたはYYMMDD形式の数値として。ただし、数値は日付として意味があります。たとえば、_19830905_および_830905_は_'1983-09-05'_として解釈されます。

@ Barmarコメント済み のように、リテラル式_2012-12-28_は算術_(2012 - 12) - 28_として評価され、これは1,972に等しくなります。

@ JW。's answer ごとに、その式を引用して有効な日付リテラル(上記の最初の形式)を取得できます。代わりに:

  • リテラルを引用しながら、日付部分間の区切り文字として他の句読文字(または文字なし)を使用できます。

    _WHERE DATE(booking_time) <= '2012_12_28'
    WHERE DATE(booking_time) <= '20121228'
    _
  • 区切り文字を削除して、リテラルを引用符で囲まずに残すことができます。

    _WHERE DATE(booking_time) <= 20121228
    _

また、列に対して関数(この場合はDATE()関数)を使用するこのようなフィルター条件を使用するには、その関数を評価するためにテーブル全体のスキャンが必要です。したがって、メリットはありません。任意のインデックスから。より検索可能な代替方法は、基準を満たす列値の範囲(つまりtimes)でより明示的にフィルタリングすることです:

_WHERE booking_time < '2012-12-28' + INTERVAL 1 DAY
_

これは、次の日より前に厳密に該当する時間は、必ず関心のある日またはその前に発生するため、同等です。列が定数式(_+_操作の結果が決定的である)と比較されるため、検索可能です。したがって、_booking_time_のインデックスを走査して、一致するすべてのレコードをすぐに見つけることができます。

11
eggyal
 SELECT * FROM ctx_bookings WHERE DATE(booking_time)<='2012-12-28' ORDER BY id ASC

この仲間を試してください

2
Nipun Jain