web-dev-qa-db-ja.com

Oracle SQLでの日付の比較

1994年6月20日以降に雇用された従業員数を表示するようにしていますが、 "JUN 'invalid identifier"というエラーが表示されます。

Select employee_id, count(*)
From Employee
Where to_char(employee_date_hired, 'DD-MON-YY') > 31-DEC-95; 
117
user1336830

31-DEC-95は文字列でも20-JUN-94でもありません。最後にいくつか追加のものが追加された数字です。これは'31-DEC-95'または'20-JUN-94'である必要があります - 一重引用符、'に注意してください。これにより、文字列比較を実行できます。

ただし、文字列比較はしていません。 あなたは日付の比較をしています。あなたはあなたの文字列を日付に変換するべきです。組み込みの TO_DATE() 関数、または 日付リテラル を使用する。

現在まで()

select employee_id
  from employee
 where employee_date_hired > to_date('31-DEC-95','DD-MON-YY')

この方法には、不要な落とし穴がいくつかあります。

  • コメントに示されているa_horse_with_no_nameのDECname__は、必ずしも12月を意味するわけではありません。 NLS_DATE_LANGUAGE および NLS_DATE_FORMAT の設定によって異なります。あなたの比較がどんなロケールでもうまくいくようにするために、代わりに datetimeフォーマットモデルMMname__を使うことができます。
  • '95年は不正確です。あなたはあなたが1995年を意味していることを知っています、しかしそれが'50であったならば、それは1950年か2050年ですか?明示的にすることが常に最善です
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

日付リテラル

日付リテラルはANSI規格の一部です。つまり、Oracle固有の関数を使用する必要はありません。リテラルを使用するときは、mustの形式で日付をYYYY-MM-DDの形式で指定します。時間要素を含めることはできません。

select employee_id
  from employee
 where employee_date_hired > date '1995-12-31'

Oracleのdateデータ型には時刻要素が含まれているため、時刻部分のない日付は1995-12-31 00:00:00と同等です。

時間部分を含める場合は、YYYY-MM-DD HH24:MI:SS[.FF0-9]という形式のタイムスタンプリテラルを使用する必要があります。

select employee_id
  from employee
 where employee_date_hired > timestamp '1995-12-31 12:31:02'

さらに詳しい情報

NLS_DATE_LANGUAGENLS_LANGUAGE から派生し、 NLS_DATE_FORMATNLS_TERRITORY から派生します。これらはデータベースを最初に作成したときに設定されますが、初期化パラメータファイルを変更することによって(本当に必要な場合のみ)、または ALTER SESSION 構文を使用してセッションレベルで変更できます。例えば:

alter session set nls_date_format = 'DD.MM.YYYY HH24:MI:SS';

これの意味は:

  • DDname__月の日にち、1 - 31
  • MMname__年の通算月、01 - 12(1月は01)
  • YYYY4桁の年 - 私の意見では、これはalways 2桁の年より良い_YYname__です。
  • HH24 1日の時間、0 - 23
  • MIname__時の分、0 - 59
  • SSname__分の秒、0から59

V$NLS_PARAMETERSsを照会することで現在の言語と日付の言語設定を確認し、V$NLS_VALID_VALUESを照会することで有効な値の全範囲を確認することができます。

参考文献


ちなみにcount(*)が欲しい場合はemployee_idでグループ分けする必要があります

select employee_id, count(*)
  from employee
 where employee_date_hired > date '1995-12-31'
 group by employee_id

これはあなたにカウントperemployee_idを与えます。

265
Ben

次のようにtruncとto_dateを使うことができます。

select TO_CHAR (g.FECHA, 'DD-MM-YYYY HH24:MI:SS') fecha_salida, g.NUMERO_GUIA, g.BOD_ORIGEN, g.TIPO_GUIA, dg.DOC_NUMERO, dg.* 
from ils_det_guia dg, ils_guia g
where dg.NUMERO_GUIA = g.NUMERO_GUIA and dg.TIPO_GUIA = g.TIPO_GUIA and dg.BOD_ORIGEN = g.BOD_ORIGEN
and dg.LAB_CODIGO = 56 
and trunc(g.FECHA) > to_date('01/02/15','DD/MM/YY')
order by g.FECHA;
4

結論、

to_charは独自の方法で機能します

そう、

MM-DD-YY または DD-MM-YYYY またはその他の形式の代わりに、常に YYYY-MM-DD という形式を使用してください。

4
akshay gulawane

あなたのクエリから:

Select employee_id, count(*) From Employee 
Where to_char(employee_date_hired, 'DD-MON-YY') > '31-DEC-95' 

1994年6月20日以降に雇用された従業員数を表示しないと思います。従業員数を表示したい場合は、次のようにします。

Select count(*) From Employee 
Where to_char(employee_date_hired, 'YYYMMMDDD') > 19940620 

私はあなたが使用できる日付を比較するためのベストプラクティスのために考える:

employee_date_hired > TO_DATE('20-06-1994', 'DD-MM-YYYY');
or
to_char(employee_date_hired, 'YYYMMMDDD') > 19940620;
2
viduka