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>
我写查询来检查最后一天是否是星期五,但我总是看到 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>