Oracle SQL'deki Tarihleri ​​Karşılaştırma


141

20 Haziran 1994'ten sonra işe alınan çalışan sayısını göstermeye çalışıyorum, ancak "JUN 'geçersiz tanımlayıcısı" hatası alıyorum. Lütfen yardım edin, teşekkürler!

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

1
Eğer birini kullanabilirsiniz da unutmayın > <yaBETWEEN '' AND ''
Andrew

Yanıtlar:


296

31-DEC-95bir dize değil 20-JUN-94. Sonuna bazı ekstra şeyler eklenmiş sayılar. Bu tek alıntı olmalı '31-DEC-95'ya da '20-JUN-94'- tek bir alıntıya dikkat etmeli '. Bu, bir dize karşılaştırması yapmanızı sağlayacaktır.

Ancak, dize karşılaştırması yapmıyorsunuz; tarih karşılaştırması yapıyorsunuz . Dizenizi bir tarihe dönüştürmelisiniz. Yerleşik TO_DATE()işlevi veya bir tarih değişmezini kullanarak .

BUGÜNE KADAR()

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

Bu yöntemin birkaç gereksiz tuzağı var

  • Yorumlarda belirtildiği gibi a_horse_with_no_name DEC, Aralık anlamına gelmez. Bu sizin NLS_DATE_LANGUAGEve NLS_DATE_FORMATayarlarınıza bağlıdır . Herhangi bir yerel ayardaki çalışma ile karşılaştırmanızın yerine tarih / saat biçimini kullanabilirsiniz.MM
  • '95 yılı kesin değil. 1995 demek istediğinizi biliyorsunuz, ama '50 ise, 1950 veya 2050 mi? Açık olmak her zaman en iyisidir
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

Tarih değişmez değerleri

Tarih değişmezi ANSI standardının bir parçasıdır, bu da Oracle'a özgü bir işlevi kullanmanız gerekmediği anlamına gelir. Değişmez değer kullanırken , tarih biçiminde belirtmeniz gerekirYYYY-MM-DD ve bir zaman öğesi ekleyemezsiniz.

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

Oracle tarih veri türünün bir saat öğesi içerdiğini, bu nedenle saat bölümü olmayan tarihin eşdeğer olduğunu unutmayın 1995-12-31 00:00:00.

Bir zaman bölümü eklemek istiyorsanız, biçimi alan bir zaman damgası hazır bilgisi kullanmanız gerekir. YYYY-MM-DD HH24:MI:SS[.FF0-9]

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

Daha fazla bilgi

NLS_DATE_LANGUAGE, türetilmiştir NLS_LANGUAGEve NLS_DATE_FORMATtüretilmiştir NLS_TERRITORY. Bunlar, veritabanını ilk oluşturduğunuzda ayarlanır, ancak yalnızca gerçekten gerekliyse - inialization parametreleri dosyanızı değiştirerek veya ALTER SESSIONsözdizimini kullanarak oturum düzeyinde değiştirilebilir . Örneğin:

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

Bu şu anlama gelir:

  • DD ayın sayısal günü, 1 - 31
  • MM yılın sayısal ayı, 01-12 (Ocak 01'dir)
  • YYYY4 basamaklı yıl - bence bu, her zaman 2 basamaklı bir yıldan daha iyidir YY, çünkü hangi yüzyıldan bahsettiğinizle ilgili bir karışıklık yoktur.
  • HH24 Günün saati, 0 - 23
  • MI saatin dakikası, 0 - 59
  • SS dakikanın ikincisi, 0-59

Geçerli dil ve tarih dili ayarlarınızı sorgulayarak V$NLS_PARAMETERSsve geçerli değerlerin tamamını sorgulayarak bulabilirsiniz V$NLS_VALID_VALUES.

daha fazla okuma


Bu arada, isterseniz count(*)gruplandırmanız gerekiremployee_id

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

Bu size başına sayıyı verir employee_id.


13
To_date () içinde bir biçim maskesi kullanmak için +1. Farklı dil ayarları nedeniyle bunun farklı ortamlarda hala başarısız olabileceğini unutmayın. DECher zaman geçerli bir ay değildir. İsim yerine sayı kullanmak genellikle daha iyidir
a_horse_with_no_name 16:12

1
Sen edebilir bir ANSI edebi bir zaman belirtmek - Eğer sadece bir belirtmeniz gerekir timestampyerine değişmez bir dateedebi: timestamp '2015-01-30 19:42:04' (ANSI SQL içinde çünkü dateveri türü bir zamanı yoktur, sadece timestampveri türü yapar).
a_horse_with_no_name

1
ANSI tarih değişmezleri gerçekten her seferinde TO_DATE ve Tarih Biçimi yazmak zorunda kalmanın karşılaştırması konusunda kısa ve öz bir yöntemdir. Benim gibi LAZY geliştiricileri için iyi . Dikkat edilmesi gereken bir şey gerçekten DATE 2016-04-01araçlar 2016-04-01 00:00:00. Bence bu sözdizimi Oracle 9i'den beri çalışıyor çünkü ANSI-SQL sözdiziminin Oracle'a tanıtıldığı yer burası.
LeOn - Han Li

1
Düşüncem son 4 yılda önemli ölçüde gelişti @ Aslan :-) 'Cevabı güncelledim. Bir tarih değişmezinin bir zaman öğesi içermediğinden bahsetmiştim, ancak belirttiğiniz gibi bunu daha açık bir şekilde çağırdım. 9i genişletilmiş destek neredeyse 6 yıl önce sona erdi ... ve 14 yıl önce serbest bırakıldı. Artık kullanıcıların büyük çoğunluğu için geçerli olmamalıdır.
Ben


6

Sonuç,

to_char kendi yolunda çalışır

Yani,

Karşılaştırma için her zaman MM-DD-YY veya DD-MM-YYYY veya başka bir biçim yerine bu YYYY-AA-GG biçimini kullanın


4

Trunc ve to_date komutlarını aşağıdaki gibi kullanabilirsiniz:

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;

2

sorgunuzdan:

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

20 Haziran 1994'ten sonra işe alınan çalışan sayısını göstermemesini düşünüyorum. Çalışan sayısını göstermek istiyorsanız, şunları kullanabilirsiniz:

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

Bence kullanabileceğiniz tarihleri ​​karşılaştırmak için en iyi uygulama:

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

-4

Tarih karaktere dönüştürüldüğünden beri tek tırnak bulunmalıdır.

Çalışanı_kimliği seçin, sayın (*)
Çalışandan
Nereye_char (çalışan_tarihi_hired, 'DD-MON-YY')> '31 -DEC-95 ';

1
Bu SQL kapalı bir tarih biçimi kullanır, her zaman çalışmaz.
Jon Heller

5
Yalnızca belirli NLS_ * ayarlarınız için iyi çalışıyor, diğer istemciler veya sunucularda çalışmayabilir. Kabul edilen cevap, açık bir tarih formatının neden önemli olduğunu açıklar.
Jon Heller

Bu yöntem, dizeleri karşılaştırır, tarihleri ​​değil. İkinci dize bir "3" ile başlar, bu yüzden karşılaştırma "alfabetik sıraya" benzer. İlginçtir, YYYY-AA-GG gibi bir biçim kullanırsanız, bu tür karşılaştırma aslında (kazara bir şekilde) çalışır. Ama elbette, tarihleri ​​tarihlerle karşılaştırmak daha iyi ...
Nick Perkins
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.