28

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

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

4

3 に答える 3

67

値を一重引用符で囲むと、確実に機能します

SELECT * 
FROM ctx_bookings 
WHERE DATE(booking_time) <= '2012-12-28' 
ORDER BY id ASC
于 2012-12-27T07:31:12.030 に答える
12

日付と時刻のリテラルで文書化されているように:

MySQLDATEは次の形式の値を認識します。

  • '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'ます。

  • 数値が日付として意味をなす場合は、いずれYYYYMMDDYYMMDDの形式の数値として。たとえば、19830905830905はとして解釈され'1983-09-05'ます。

@Barmarがコメントしたように、リテラル式2012-12-28は算術として評価されます(2012 - 12) - 28。これは1,972に相当します。

@JW 。の回答によると、その式を引用して、有効な日付リテラル(上記の最初の形式)を取得できます。または:

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

    WHERE DATE(booking_time) <= '2012_12_28'
    WHERE DATE(booking_time) <= '20121228'
    
  • 区切り文字を削除して、文字通りの引用符を付けないでおくことができます。

    WHERE DATE(booking_time) <= 20121228
    

また、列に対して関数(この場合はDATE()関数)を使用するこのようなフィルター基準を使用すると、その関数を評価するために全表スキャンが必要になるため、インデックスの恩恵を受けられないことにも注意してください。より引数可能な代替案は、基準を満たす列値の範囲(つまり、回)をより明示的にフィルタリングすることです。

WHERE booking_time < '2012-12-28' + INTERVAL 1 DAY

厳密に翌日より前に当たる時間は、必然的に対象の日またはそれ以前に発生するため、これは同等です。列が定数式(+演算の結果が決定論的である)と比較されるため、引数可能です。したがって、インデックスをbooking_timeトラバースして、一致するすべてのレコードをすぐに見つけることができます。

于 2012-12-27T07:55:18.313 に答える
2
 SELECT * FROM ctx_bookings WHERE DATE(booking_time)<='2012-12-28' ORDER BY id ASC

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

于 2012-12-27T07:32:19.833 に答える