2016-05-12 19 views
0

ソーラーの日付の列ですが、そのタイプはvarcharです(1395-02)の間隔にあるすべての行を選択したいのですが、2行から1行しか取得しません。 ここに私が試したことがありますMysql日付太陽の日付

SELECT * FROM `products_records` 
    WHERE Date_FORMAT(`products_records`.`Inserted_Date`,'%Y-%m')='1395-02' 

注:データベースで1395年2月30日のようないくつかの日付が0000-00-00に変更した、ザッツ私はVarchareの代わりに、このコラム

答えて

0

初の日付を使用する理由は、使用していることに注意してくださいDATE_FORMAT()を意図した目的外に使用してください。 DATE_FORMAT()の最初の引数は文字列ではなくdatetime値とみなされますが、MySQLは暗黙的なキャストで非常に寛大ですので、技術的に有効ではない関数を一掃することができます。あなたは実際に暗黙的にあなたの文字列を日付にキャストしているし、日付を期待する関数を使用して...しかし、あなたの日付のいくつかは無効なので、暗黙的なキャストはおそらく失敗しているでしょう。クエリを実行すると、SHOW WARNINGS;がこれを明らかにします。

実際には、理論的にはSTR_TO_DATE()を使用して文字列を適切な日時に変換し、その結果をDATE_FORMAT()の最初の引数として使用する必要があります。

WHERE節のほとんどの関数の引数としてカラムを使用したくないという基本的なルールに違反しているので、これはまだ間違った解決策になるでしょう。表の各行の式を評価し、索引を使用して問合せを最適化することはできません。 「sargability」と呼ばれるものを失い、クエリのサイズが大きくなるにつれてクエリが遅くなります。これは、MySQLだけでなく、RDBMSの一般的な制限です。

定数は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の範囲ではなく、月と日の値が合法であることが必要です。 strictモードを無効にすると、 '2004-04-31'などの無効な日付は '0000-00-00'に変換され、警告が生成されます。 strictモードを有効にすると、無効な日付がエラーを生成します。私は、無効な日付を使用するには理由があったことがありませんが、このような日付を許可するには、ALLOW_INVALID_DATES.

http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_allow_invalid_dates

を有効にすると、それは、日付/時刻関数は、また、それらの上にチョークであろうと理にかなっているが、この設定それらの値が期待どおりに機能するために必要なものかもしれません。

+0

ありがとう、その最高の答えは、私のために働いた –