2015-10-15 11 views
5

MyテーブルmyTabには、データ型がDATEのstartDateというカラムがあります。この列のデータはdd.mm.yyyyのように格納されます。LIKE '%' on DATE

は今、私はこのクエリを使用してデータを取得しようとしている:

SELECT * FROM myTab WHERE startDate like '%01.2015" 

どういうわけか、それは動作しませんし、私は理由を知りません。

誰かが助けてくれることを願っています。

+0

あなたは2015年1月の使用 ' to_char関数(たstartDate、「月-YYYY」)= 'Jan-内のすべての行をしたい場合2015 '; ' – Mihai

+0

[DATEのOracle SQLの比較で間違った結果が返される]をご覧ください(http://stackoverflow.com/questions/29005398/oracle-sql-comparison-of-dates-returns-wrong-result/29005418# 29005418) –

答えて

18

日付のテキスト検索を行うには、日付をテキストに変換する必要があります。

あなたが探したいものの最初と最後の日付を計算し、それらの間のすべてを取得する方が効率的です。その方法は、それが代わりにテキストパターンマッチの数値比較として行われます、そして存在する場合には、インデックスを利用することができます:

SELECT * FROM myTab WHERE startDate >= DATE '2015-01-01' AND startDate < DATE '2015-02-01' 
+0

もし** WHY **の日付範囲**を使用していることに言及していただければ幸いです。基本的には、それはパフォーマンス、すなわち(もしあれば)「B *ツリーインデックス」の使用に関するものである。 –

+0

@LalitKumarB:良い点。 – Guffa

+0

"*それは、テキストパターンマッチではなく、単純な数値比較です。*"いいえ、それはそうではありません。数値比較ではありません。 Oracleでは、** DATE **と** NUMBER **はまったく異なっています。 –

2

フィールドタイプがある場合は、「DATE」その値は次のように保存されていません文字列は、それは、Oracleによって管理番号ですので、あなたは、文字列に変換する必要があります:あなたはまた、SQLクエリで日付の範囲を使用することができます

SELECT * FROM myTab WHERE to_char(startDate, 'MM.YYYY') = '01.2015'; 

SELECT * FROM myTab 
WHERE startDate 
BETWEEN to_date('01.01.2015', 'DD.MM.YYYY') 
AND  to_date('31.01.2015', 'DD.MM.YYYY'); 
+1

暗黙的なデータ変換については、まずこちらを参照してください。http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements002htm#i53062この場合、Oracleは日付をvarcharに自動的に変換しますが、答えは正確ではありません。 – krokodilko

+0

to_char()は明示的です。http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements002。 htm#SQLRF51054 – mbk

2
SELECT * FROM myTab WHERE TO_CHAR(startDate,'dd.mm.yyyy') LIKE '%01.2015' 
+0

あなたのやり方はちょっとうまくいった。今、私は他の日付がうまくいかない問題を持っています。私が '%01.2013'を使用しようとすると、私はデータを取得しませんが、この範囲に日付があることを知っています... – Ovoxo

+0

@Lalit、少しでも気分を緩和することをお勧めしますか?この回答は「完全に間違っている」というわけではありません。実際には、この答え*はうまくいくでしょう。ただし、問題を解決する方法はもっとはるかに優れていますが、暗黙的なデータ型変換には依存しません。 –

+0

@Jeffrey、十分に公正:-) –

1

実際の質問について「どういうわけか、うまくいかず、なぜかわからない」

オラクルDATEからVARHCAR2への暗黙的な変換を行う、しかし、それはおそらくあなたがあなたのクエリに使用するものと異なるデフォルトNLS_DATE_FORMATを使用しています。

1

この列のデータは、dd.mm.yyyyのように格納されます。

オラクルは、表示される形式で日付を保存しません。独自の形式で内部的に7バイトで格納し、各バイトはdatetime値の異なるコンポーネントを格納します。

たstartDateは「%01.2015"

のようにあなたが無意味であるSTRING、とDATEを比較している

ビューのパフォーマンスの観点から、あなたがすべきです日付範囲条件を使用してください。したがって、通常のINDEXが日付列にある場合それが使用されます。

SELECT * FROM table_name WHERE date_column BETWEEN DATE '2015-01-01' AND DATE '2015-02-01' 

日付の範囲条件パフォーマンスの面で優れている理由を理解することは、私の答えhereを見ています。

0

私はそのように私の問題を解決しました。改善のための提案をありがとうございます。 C#の例

string dd, mm, aa, trc, data; 
dd = nData.Text.Substring(0, 2); 
mm = nData.Text.Substring(3, 2); 
aa = nData.Text.Substring(6, 4); 
trc = "-"; 
data = aa + trc + mm + trc + dd; 

"Select * From bdPedidos Where Data Like '%" + data + "%'"; 
0

これはhttps://stackoverflow.com/a/42429550/1267661答えの問題を解決するためです。

Oracleでは、「date」型の列は数値でも文字列でもなく、年、月、日、時、分、秒の「日時」の値です。 デフォルトの時間は深夜「夜12時00分00秒」

クエリ常にある:

Select * From bdPedidos Where Data Like '%" + data + "%'" 

日付列は、Oracle力「のように」を使用して、文字列ではないので、すべての状況では動作しません日付値から文字列値への変換を行います。 文字列の値は、特定のOracleインスタンスが日付を文字列として表示するようにNLS_DATE_FORMATパラメータを設定した方法に応じて、年月日または月日曜日または日月曜日のいずれかになります。

日にすべての可能な時間をカバーする正しい方法は次のとおりです。

Select * 
From bdPedidos 
Where Data between to_date('" + data + " 00:00:00','yyyy-mm-dd hh24:mi:ss') 
       and to_date('" + data + " 23:59:59','yyyy-mm-dd hh24:mi:ss') 
+0

クエリはC#の内部に構築された文字列なので、開始引用符と最後の引用符が必要です – alvalongo