Oracle SQL में Dates की तुलना करना


141

मैं इसे 20 जून, 1994 के बाद काम पर रखे गए कर्मचारियों की संख्या प्रदर्शित करने के लिए प्राप्त करने की कोशिश कर रहा हूं, लेकिन मुझे "JUN 'अमान्य पहचानकर्ता कहते हुए एक त्रुटि मिलती है। कृपया मदद करें, धन्यवाद!

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

1
ध्यान दें कि आप > <या तो उपयोग कर सकते हैं याBETWEEN '' AND ''
एंड्रयू

जवाबों:


296

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 टिप्पणियों में उल्लेख किया गया है DEC, जरूरी नहीं कि दिसंबर का मतलब है। यह आपके NLS_DATE_LANGUAGEऔर NLS_DATE_FORMATसेटिंग्स पर निर्भर करता है । यह सुनिश्चित करने के लिए कि किसी भी लोकेल में काम के साथ आपकी तुलना आप इसके बजाय डेटाइम प्रारूप मॉडल का उपयोग कर सकते हैंMM
  • वर्ष '95 अथाह है। आप जानते हैं कि आपका मतलब 1995 है, लेकिन अगर यह '50 था, तो क्या यह 1950 या 2050 है? यह हमेशा स्पष्ट होना सबसे अच्छा है
select employee_id
  from employee
 where employee_date_hired > to_date('31-12-1995','DD-MM-YYYY')

दिनांक शाब्दिक

डेट शाब्दिक ANSI मानक का हिस्सा है, जिसका अर्थ है कि आपको Oracle विशिष्ट फ़ंक्शन का उपयोग करने की आवश्यकता नहीं है। शाब्दिक का उपयोग करते समय आपको प्रारूप में अपनी तिथि निर्दिष्ट करनी चाहिएYYYY-MM-DD और आप समय तत्व को शामिल नहीं कर सकते।

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

याद रखें कि ओरेकल डेट डेटाइप में एक टाइम इलेमेंट शामिल है, इसलिए बिना टाइम पार्ट के तारीख समान है 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_LANGUAGEसे लिया गया है NLS_LANGUAGEऔर NLS_DATE_FORMATसे लिया गया है NLS_TERRITORY। ये तब सेट किए जाते हैं जब आपने शुरुआत में डेटाबेस बनाया था, लेकिन ALTER SESSIONसिंटैक्स का उपयोग करके सत्रीय स्तर पर - केवल अपनी inialization पैरामीटर्स फ़ाइल को बदलकर बदला जा सकता है । उदाहरण के लिए:

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

इसका मतलब है की:

  • DD महीने का सांख्यिक दिन, 1 - 31
  • MM वर्ष का सांख्यिक महीना, 01 - 12 (जनवरी 01 है)
  • YYYY4 अंक वर्ष - मेरी राय में यह हमेशा 2 अंकों के वर्ष से बेहतर होता है YYक्योंकि आप जिस सदी का जिक्र कर रहे हैं उससे कोई भ्रम नहीं है।
  • HH24 दिन का घंटा, 0 - 23
  • MI घंटे का मिनट, 0 - 59
  • SS मिनट का दूसरा, 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

यह आपको प्रति गणना देता है employee_id


13
+1 in_date () में एक प्रारूप मास्क का उपयोग करने के लिए। ध्यान दें कि यह अभी भी अलग-अलग वातावरण पर अलग-अलग भाषा सेटिंग्स के कारण विफल हो सकता है। DECजरूरी नहीं कि हमेशा वैध महीना ही हो। आमतौर पर नामों के बजाय संख्याओं का उपयोग करना बेहतर होता है
a_horse_with_no_name

1
आप एक एएनएसआई शाब्दिक के साथ एक समय निर्दिष्ट कर सकते हैं - आपको केवल timestampशाब्दिक के बजाय एक शाब्दिक निर्दिष्ट करने की आवश्यकता है date: timestamp '2015-01-30 19:42:04' (क्योंकि एएनएसआई एसक्यूएल में dateडेटा प्रकार का समय नहीं होता है, केवल timestampडेटा प्रकार होता है)।
a_horse_with_no_name

1
ANSI दिनांक शाब्दिक वास्तव में TO_DATE और दिनांक-स्वरूप टाइप करने की तुलना में एक संक्षिप्त तरीका है। मेरे जैसे LAZY डेवलपर्स के लिए अच्छा है। नोटिस करने के लिए एक बात वास्तव में DATE 2016-04-01साधन 2016-04-01 00:00:00है। और मुझे लगता है कि यह सिंटैक्स Oracle 9i के बाद से काम करता है क्योंकि यह वह जगह है जहाँ ANSI-SQL सिंटैक्स Oracle में पेश किया गया था।
लियोन - हान ली

1
मेरी सोच पिछले 4 वर्षों में काफी विकसित हुई है @Leon :-) 'मैंने उत्तर को अपडेट कर दिया है। मैंने उल्लेख किया था कि एक तारीख शाब्दिक में एक समय तत्व शामिल नहीं था, लेकिन मैंने इसे स्पष्ट रूप से कहा है जैसा आपने कहा है। 9i विस्तारित समर्थन लगभग 6 साल पहले समाप्त हो गया था ... और 14 साल पहले जारी किया गया था। यह उपयोगकर्ताओं के विशाल बहुमत के लिए किसी भी अधिक प्रासंगिक नहीं होना चाहिए।
बेन


6

निष्कर्ष,

to_char अपने तरीके से काम करता है

इसलिए,

हमेशा MM-DD-YY या DD-MM-YYYY या किसी अन्य प्रारूप के बजाय तुलना के लिए इस प्रारूप YYYY-MM-DD का उपयोग करें


4

आप ट्रंक और 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;

2

आपकी क्वेरी से:

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

मुझे लगता है कि 20 जून 1994 के बाद काम पर रखे गए कर्मचारियों की संख्या को प्रदर्शित नहीं करना है। यदि आप कर्मचारियों की संख्या दिखाना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

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;

-4

एकल उद्धरण वहाँ होना चाहिए, क्योंकि तिथि चरित्र में परिवर्तित हो जाती है।

कर्मचारी चयन करें, गणना करें (*)
कर्मचारी से
जहां_चर (कर्मचारी_डेट_हेड, 'डीडी-मोन-वाईवाई')> '31 -DEC-95 ';

1
यह एसक्यूएल एक निहित तारीख प्रारूप का उपयोग करता है, यह हमेशा काम नहीं करेगा।
जॉन हेलर

5
यह केवल आपके विशिष्ट NLS_ * सेटिंग्स के लिए ठीक काम कर रहा है, यह अन्य क्लाइंट या सर्वर पर काम नहीं कर सकता है। स्वीकृत उत्तर बताता है कि स्पष्ट तिथि प्रारूप क्यों महत्वपूर्ण है।
जॉन हेलर

यह विधि तार की तुलना कर रही है, तिथियों की नहीं। दूसरा तार एक "3" से शुरू होता है, इसलिए तुलना "वर्णमाला क्रम" की तरह काम करती है। दिलचस्प है, यदि आप YYYY-MM-DD जैसे प्रारूप का उपयोग करते हैं तो इस प्रकार की तुलना वास्तव में काम करती है (दुर्घटना के अनुसार)। लेकिन निश्चित रूप से, तारीखों से तारीखों की तुलना करना बेहतर है ...
निक पर्किन्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.