1

私はこの Oracle データベースを持っており、この形式の日付のリストがあります: mm/dd/yy 0:00:00 AM/PM(1 月の場合は 01 ではなく 1、01 の場合は 1 など)。

次のようなクエリを実行すると、次のようになります。

select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');

次のエラーが表示されますORA-01843: not a valid month。27 が有効な月であることもわかりませんが、試してみるとその入力が受け入れられます

予想される日付形式に変更しようとすると:

  1. m/dd/yy
  2. mm/dd/yyyy
  3. m/d/yy

次のエラーが表示されます。ORA-01821: date format not recognized

に切り替えるとdd/mm/yy、ある程度は機能しますが、実際には機能しません。無効な結果が得られます。

ただし、これは機能します。

select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') 

PL/SQL スクリプトは、次の追加で壊れています。

AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');

上記のコードをこれに置き換えると:

SELECT to_date(DATELIST, 'dd/mm/yy') 
    FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015', 'mm/dd/yy')
    AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy');

これは機能し、100 万倍高速ですが、日付範囲を正しく解析しません。より小さいか等しい ( <=) 演算子は8/27/2015、 との間のデータのみを取得し9/26/2015ます。2015 年 8 月 27 日から 2015 年 9 月 27 日になるはずではありませんか?

そこで、最後の行を次のように変更します。

AND DATELIST <= to_date('9/27/2015', 'mm/dd/yy') + 1

...そしてそれは機能しますが、私がこれを正しく扱っているようには見えません。

私は何を間違っていますか?また、これを行うためのより良い、より効率的な方法があれば、私はすべて耳にします.

4

2 に答える 2

2

元の質問には多くの問題があります。ここでそれらの一部またはすべてに対処しようとします。

When I try a query such as:
select DATELIST from CORE.DATE_TEST
where to_date(DATELIST) >= to_date('8/27/2015', 'mm/dd/yy') AND to_date(DATELIST, 'mm/dd/yy') <= to_date('9/27/2015', 'mm/dd/yy');
It gives me the following error: ORA-01843: not a valid month

指定するときに日付形式を指定していないto_date(DATELIST)ため、デフォルトの日付形式の NLS 設定がデフォルトになります。TO_DATE を使用するときは常に日付形式を指定して、これが起こらないようにし、日付形式が明示的であることを確認する必要があります (そして、使用yyしているのに 4 桁の年を指定しているため、使用する必要がありますyyyy)。

DATELIST代わりにこれを試してください(がデータ型であると仮定しますDATE):

select TO_CHAR(DATELIST, 'DD-MON-YYYY HH24:MI:SS') -- Use whatever date format is clearest to you
  from CORE.DATE_TEST
 where DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss') AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');

の場合DATELISTVARCHAR2、値が列内に格納されている日付形式を確認し、それに応じてクエリをフォーマットする必要があります。

より小さいか等しい (<=) 演算子は、2015 年 8 月 27 日から 2015 年 9 月 26 日までのデータのみを取得します。2015 年 8 月 27 日から 2015 年 9 月 27 日になるはずではありませんか?

日付の時間部分を使用TO_DATEして指定しない場合、時間、分、および秒のデフォルトは 00:00:00 になります。完全な日付範囲が必要な場合は、より明示的にしてください。

SELECT to_date(DATELIST, 'dd/mm/yy hh24:mi:ss') 
    FROM CORE.DATE_TEST
WHERE DATELIST >= to_date('8/27/2015 00:00:00', 'mm/dd/yyyy hh24:mi:ss')
    AND DATELIST <= to_date('9/27/2015 23:59:59', 'mm/dd/yyyy hh24:mi:ss');

DATELISTクエリがはるかに高速な理由は、列にインデックスがありTO_DATETO_DATE(DATELIST, 'mm/dd/yyyy').

のデータ型がそのままでDATELISTある場合はDATE、そのままにしておきます。そうである場合VARCHAR2は、日付の書式設定に関する追加の問題があります。

それが役に立てば幸い

編集:

あなたの問題は、DATEデータ型DATELISTの非表示の時間部分に関係していると思います。

値がある場合: 09/27/2015 10:35:12

その日付の 10:35:12 の部分を気にしなくても、まだそこにあります。次に、次の where 句を使用しようとすると:

WHERE DATELIST >= TO_DATE('09/26/2015', 'MM/DD/RRRR')
  AND DATELIST <= TO_DATE('09/27/2015', 'MM/DD/RRRR');

2015 年 9 月 27 日 00:00:00 よりも大きいため、値は取得されません。

上限を 1 日分上げるか、時間部分を指定する必要があります。例:

WHERE DATELIST >= TO_DATE('09/26/2015 00:00:00', 'MM/DD/RRRR HH24:MI:SS')
  AND DATELIST <= TO_DATE('09/27/2015 23:59:59', 'MM/DD/RRRR HH24:MI:SS');

EDIT2:OPと協力して、彼はこれがうまくいったと言っています:

SELECT to_date(DATELIST, 'dd/mm/yy') as Date_Accessed 
  FROM CORE.DATE_TEST 
 WHERE (trunc(DATELIST) >= to_date('9/27/2015', 'mm/dd/yy')) 
   AND (trunc(DATELIST) <= to_date('9/30/2015', 'mm/dd/yy'));

ただし、これは DATELIST 列のインデックスを無効にします。

于 2015-10-01T15:07:43.723 に答える
0

to_date を使用する代わりに、ANSI 日付リテラルを使用します。

DATE '2015-09-27'

オラクルのドキュメントから:

ANSI 日付リテラルには時間部分が含まれていないため、正確にこの形式 ('YYYY-MM-DD') で指定する必要があります。

于 2015-10-01T15:26:30.203 に答える