oracle中的日期计算

Counting date in oracle

我写查询来检查最后一天是否是星期五,但我总是看到 2 而不是 4。 任何建议该查询有什么问题?

 (
 SELECT (
        CASE
               WHEN To_char(due_date,'DAY','nls_date_language=english')='FRIDAY' THEN 4
               ELSE 2
        END)
 FROM   capagency.pa_instances pa,
        capagency.users u
 WHERE  pa.idusr = u.idusr
 AND    pa.entity_id = a.ceid
 AND    p.payment_date BETWEEN pa.begin_date AND    pa.due_date.

好的,我添加了 trim,但我得到的结果仍然是错误的,我得到的不是值 4,而是值 2。

(
select convert(u.Full_Name, 'UTF8')
from Capagency.Pa_Instances Pa,
     Capagency.Users u
where Pa.Idusr = u.Idusr
AND Pa.Entity_Id = a.Ceid
and p.payment_date BETWEEN pa.begin_Date and Pa.DUE_DATE + (
    CASE WHEN (TRIM(TO_CHAR(due_date,'DAY','nls_date_language=english'))='FRIDAY')
      THEN 4 ELSE 2 END)
and rownum = 1
) "Collector",

首先我得到

(select case
  when (TRIM(To_char(due_date,'DAY','nls_date_language=english'))) = 'FRIDAY'
    THEN 4 else 2 END
from Capagency.Pa_Instances Pa,
     Capagency.Users u
where Pa.Idusr = u.Idusr
AND Pa.Entity_Id = a.Ceid
and p.payment_date BETWEEN pa.begin_Date and Pa.DUE_DATE

所以我看到那一天是星期五,但仍然从 else 中获得值 2。我知道 between 是如何工作的,并且在周五以外的某些日子里工作正常,我获得了正确的值。

我仍然想知道为什么我检查

case when (TRIM(To_char(due_date,'DAY','nls_date_language=english'))) = 'FRIDAY'

它总是假的,所以我的值总是 2 而不是 4。

这应该有望证明发生了什么:

select to_char(to_date('13/02/2015', 'dd/mm/yyyy'), 'DAY','nls_date_language=english') dy,
       replace(to_char(to_date('13/02/2015', 'dd/mm/yyyy'), 'DAY','nls_date_language=english'), ' ', '*') dy_show_spaces,
       to_char(to_date('13/02/2015', 'dd/mm/yyyy'), 'fmDAY','nls_date_language=english') fmdy,
       replace(to_char(to_date('13/02/2015', 'dd/mm/yyyy'), 'fmDAY','nls_date_language=english'), ' ', '*') fmdy_show_spaces
from   dual;

DY        DY_SHOW_SPACES FMDY   FMDY_SHOW_SPACES
--------- -------------- ------ ----------------
FRIDAY    FRIDAY***      FRIDAY FRIDAY      

also

简而言之,fm 修饰符否定了在结果字符串上使用 TRIM 的需要。

来自文档,

DAY 格式模型 -

Name of day, padded with blanks to display width of the widest name of day in the date language used for this element.

您需要将 TRIM 右边的空格填充为 DAY 格式。将查询修改为 -

TRIM(To_char(due_date,'DAY','nls_date_language=english'))='FRIDAY'

例如,

SQL> SELECT LENGTH(trim(TO_CHAR(hiredate, 'DAY', 'nls_date_language=AMERICAN'))) dt_trim,
  2    LENGTH(TO_CHAR(hiredate, 'DAY', 'nls_date_language=AMERICAN')) dt,
  3    TO_CHAR(hiredate, 'DAY', 'nls_date_language=AMERICAN') DAY
  4  FROM emp
  5  /

   DT_TRIM         DT DAY
---------- ---------- ---------
         9          9 WEDNESDAY
         6          9 FRIDAY
         6          9 SUNDAY
         8          9 THURSDAY
         6          9 MONDAY
         6          9 FRIDAY
         7          9 TUESDAY
         8          9 THURSDAY
         7          9 TUESDAY
         7          9 TUESDAY
         9          9 WEDNESDAY

   DT_TRIM         DT DAY
---------- ---------- ---------
         8          9 THURSDAY
         8          9 THURSDAY
         8          9 SATURDAY

14 rows selected.

SQL>

所以您看到 DAY 列右侧填充的空格了吗?我会说最好使用 DY 格式,它只有 3 个字符。

或者,使用TRIM。让我们看一下使用 HIREDATE 列的类似测试用例 EMP table -

SQL> SELECT
  2    CASE
  3      WHEN trim(TO_CHAR(hiredate, 'DAY', 'nls_date_language=AMERICAN'))='FRIDAY'
  4      THEN 4
  5      ELSE 2
  6    END dt,
  7    TO_CHAR(hiredate, 'DAY', 'nls_date_language=AMERICAN') dt_1
  8  FROM emp
  9  /

        DT DT_1
---------- ---------
         2 WEDNESDAY
         4 FRIDAY
         2 SUNDAY
         2 THURSDAY
         2 MONDAY
         4 FRIDAY
         2 TUESDAY
         2 THURSDAY
         2 TUESDAY
         2 TUESDAY
         2 WEDNESDAY

        DT DT_1
---------- ---------
         2 THURSDAY
         2 THURSDAY
         2 SATURDAY

14 rows selected.

SQL>