سؤال

أحتاج إلى العثور على بعض السجلات التي تم إنشاؤها في مجموعة من الأرباع.على سبيل المثال، أبحث عن جميع السجلات التي تم إنشاؤها بين الربع الرابع من عام 2008 والربع الأول من عام 2010.لدي هذا في جملة WHERE الخاصة بي:

...and r.record_create_date between to_date('2008 4','YYYY Q')
                                and to_date('2010 1','YYYY Q')

لكن أوراكل تقول: ORA-01820: format code cannot appear in date input format.ال Q هو رمز تنسيق تاريخ صالح، لذا لست متأكدًا مما حدث.هل هذه طريقة صالحة للعثور على القيم بين أرباع التقويم، أم أن هناك طريقة أفضل؟


مثير للاهتمام أيضًا، وربما ذو صلة، إذا قمت بتنفيذ هذا:

select to_date('2009','YYYY') from dual;

القيمة المعروضة في IDE الخاص بي هي 2009-08-01.كنت أتوقع 2009-08-04, ، منذ اليوم يكون 2010-08-04.

هذا:

select to_date('2009 1','YYYY Q') from dual;

بالطبع، فشل.

(اوراكل 10 جرام)

هل كانت مفيدة؟

المحلول

يقول أوراكل: ORA-01820: format code cannot appear in date input format. ال Q هو رمز تنسيق تاريخ صالح ، لذلك لست متأكدًا مما حدث.

انظر العمود الثاني من الجدول 2.15 في http://download.oracle.com/docs/cd/b19306_01/server.102/b14200/sql_elements004.htm#i34948. لا يُسمح بجميع عناصر التنسيق عند التحويل إلى التواريخ ، والجداول الزمنية ، إلخ.

أوصي ضد الاستخدام بين الشيكات النطاق التاريخ. غالبًا ما يفوت الناس القيم خلال يوم النهاية الذي يتوقع إدراجه. لذلك أود أن أترجم:

and r.record_create_date between to_date('2008 4','YYYY Q')
                             and to_date('2010 1','YYYY Q')

ل

and to_date('2008-10-01', 'YYYY-MM-DD') <= r.record_create_date 
and record_create_date < to_date('2010-04-01', 'YYYY-MM-DD') -- < beginning of 2Q2010.

نصائح أخرى

سأل أحدهم السؤال نفسه عن OTN: http://forums.oracle.com/forums/thread.jspa؟threadid=1081398&tstart=255

جوهر القضية هو أنه يمكنك ليس حدد "Q" في وظيفة to_date.

بالنظر إلى أنك تحدد بالفعل جزءًا من التاريخ ، فلماذا لا تقدم بأكمله تاريخ؟ مانع أيضًا to_date('2010 1','YYYY Q') سوف يعطيك 1 يناير 2010 عندما تريد حقًا 31 مارس 2010 ... في منتصف الليل.

نظرًا لأن العلاقة بين الأرباع والأشهر هي واحد إلى متعدد، فليس من المنطقي إجراء TO_DATE('2008 1', 'yyyy q');ما التاريخ الذي يجب إعادته؟أول الربع، نهاية الربع،...؟(من ناحية أخرى، فإن تحويل تاريخ إلى ربع - مثل TO_CHAR(SYSDATE, 'yyyy q') أمر منطقي لأن تاريخًا محددًا موجود فقط في ربع واحد.)

لذلك، إذا كنت تريد استعلامًا يبحث عن تاريخ يقع بين ربعين، فسيتعين عليك "إنشاء استعلام خاص بك" (مع ذكر تواريخ بداية/نهاية ربع السنة بشكل صريح).

كملاحظة جانبية، إذا كان أي شخص يفكر في عدم استخدام TO_DATE، فيرجى عدم استخدام أشياء مثل:حيث تقع قيمة date_value بين "سلسلة التاريخ 1" و"سلسلة التاريخ 2" بدون الدالة TO_DATE.ويفترض وجود تنسيق تاريخ افتراضي وفي حالات معينة يمكنه تجنب الفهارس التي يحتمل أن تكون مفيدة تمامًا.

فيما يلي مثال واحد حيث يمكن أن يكون لنفس الاستعلام نتيجة مختلفة.

select sysdate from dual where sysdate between '1-Jan-10' and '31-Dec-10';


SYSDATE
---------
04-AUG-10

SQL> alter session set nls_date_format = 'YYYY-MM-DD';

Session altered.

SQL> select * from dual where sysdate between '1-Jan-10' and '31-Dec-10'; 

no rows selected

(لاحظ أنه في المثيل الثاني لم يتم إرجاع أي خطأ.إنه يفترض فقط 10 يناير 0001 وديسمبر.العاشر، 0031.)

أعتقد أن أفضل طريقة هي فقط إدخال تاريخ بدء الربع وتواريخ نهاية الربع دون أن يزعجك TO_DATE. أعتقد أنه إذا كنت تستخدم

between '1-Jan-10' and '31-Dec-10'

على سبيل المثال ، لا تحتاج (في أوراكل) إلى to_date وليس أكثر صعوبة من الكتابة في رقم الربع

للحساب في أوراكل في اليوم الأول من الربع واليوم الأخير من الربع من العام والربع: أستخدم الحقيقة

start_month = -2 + 3 * Quarter

last_month = 3 * Quarter

variable v_year    number

variable v_quarter number

exec :v_year     :=2017

exec :v_quarter:=4

select :v_year    as year,
       :v_quarter as quarter,
       to_date(:v_year||to_char(-2+3*:v_quarter,'fm00'),'yyyymm')        as quarter_start,
       last_day(to_date(:v_year||to_char(3*:v_quarter,'fm00')||'01 23:59:59','yyyymmdd hh24:mi:ss')) as quarter_end
from dual a;


YEAR|QUARTER|QUARTER_START      |QUARTER_END        
2017|      4|2017-10-01 00:00:00|2017-12-31 23:59:59
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top