首先,請注意,您在使用DATE_FORMAT()
超出其預定用途。 DATE_FORMAT()
的第一個參數應該是一個日期時間值 - 不是字符串 - 但是MySQL對它的隱式轉換非常慷慨,所以它允許你擺脫技術上對該功能的有效使用。實際上,你隱式地將字符串轉換爲日期,然後使用一個期望日期的函數......但某些日期是無效的,因此隱式轉換可能會失敗。運行您的查詢後,SHOW WARNINGS;
可能會揭示這一點。
實際上,您理論上應該使用STR_TO_DATE()
將字符串轉換爲適當的日期時間,然後使用該結果作爲DATE_FORMAT()
的第一個參數。
但是,這仍然是一個錯誤的解決方案,因爲它違反了基本規則,您不希望使用列作爲WHERE
子句中大多數函數的參數...因爲當您這樣做時,服務器必須評估表中每一行的表達式,並且您的索引不能用於優化查詢。你失去了所謂的「sargability」,並且隨着表的增長,查詢變慢。這是一般RDBMS的侷限性,而不僅僅是MySQL。
更好的是使用常數WHERE inserted_date >= '1395-02-01' AND inserted_date < '1395-03-01'
。這樣,如果索引可用,它可以顯着提高您的性能。
因爲你的日期是yyyy-mm-dd格式,所以它們的詞彙順序恰好也是按時間順序排列的,所以即使上面的查詢將在當前設置中使用字符串比較進行評估,答案仍然會是正確的,並且查詢計劃將是最佳的。如果日期實際上是以日期存儲的,這仍然是首選形式 - 不使用WHERE
中的函數。
但是,您也希望使用無效日期,您的服務器需要ALLOW_INVALID_DATES
包含在@@SQL_MODE
中。那麼任何一個月都可以有31天。我不知道爲什麼這實際上是一個功能,但它在這裏:
服務器要求月份和日期值是合法的,而不是分別在1到12和1到31範圍內。禁用嚴格模式後,無效日期(如「2004-04-31」)將轉換爲「0000-00-00」,並生成警告。啓用嚴格模式後,無效日期會生成錯誤。要允許這樣的日期,使ALLOW_INVALID_DATES.
http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_allow_invalid_dates
雖然我從來沒有一個理由使用無效的日期,它按理說,日期/時間函數會窒息在他們身上,但這項設定可能是爲了讓這些值按預期工作所需要的。
謝謝,它最好的答案,爲我工作 –