转换为日期格式oracle

9udxz4iz  于 2023-02-15  发布在  Oracle
关注(0)|答案(3)|浏览(136)

我在表my_table中有一个字段c_days,它接受数值 从1到31。在此字段中,从1到9的数字是个位数。
我在写一个条件,如果c_day大于今天,那么你需要以to_date的日期格式显示c_day,如果小于今天,那么以日期格式显示c_day,只显示下一个月。
例如,c_day为14,今天是第8个数字,因此需要显示日期14.02.2023,如果c_day等于5,则需要显示下一个月的日期05.03.2023
我做了这样的事情:

SELECT 
   C_DAY,
   CASE
     WHEN C_DAY >= TO_CHAR(SYSDATE, 'DD') THEN 
       TO_DATE(C_DAY || '.' || TO_CHAR(SYSDATE, 'MM') || '.' || TO_CHAR(SYSDATE, 'YYYY'), 'dd.mm.yyyy')
     WHEN C_DAY < TO_CHAR(SYSDATE, 'DD') THEN
       TO_DATE(C_DAY || '.' || TO_CHAR(SYSDATE, 'MM') || '.' || TO_CHAR(SYSDATE, 'YYYY'), 'dd.mm.yyyy')
     WHEN C_DAY IS NULL THEN
       null
   END AS new_field
FROM my_table

问题是最终结果未转换为日期格式,我认为这是日期可以显示为1.03.2023、7.03.2023的原因,因此我尝试将其转换为

TO_CHAR(C_DAY, 'fm00')

然后这样做:

SELECT 
   C_DAY,
   CASE
     WHEN TO_CHAR(C_DAY, 'fm00') >= TO_CHAR(SYSDATE, 'DD') THEN 
       TO_DATE(TO_CHAR(C_DAY, 'fm00') || '.' || TO_CHAR(SYSDATE, 'MM') || '.' || TO_CHAR(SYSDATE, 'YYYY'), 'dd.mm.yyyy')
     WHEN TO_CHAR(C_DAY, 'fm00') < TO_CHAR(SYSDATE, 'DD') THEN
       TO_DATE(TO_CHAR(C_DAY, 'fm00') || '.' || TO_CHAR(SYSDATE, 'MM') || '.' || TO_CHAR(SYSDATE, 'YYYY'), 'dd.mm.yyyy')
     WHEN C_DAY IS NULL THEN
       null
   END AS new_field
FROM my_table

但它甚至不工作,它显示一个错误

nafvub8i

nafvub8i1#

您可以使用以下命令执行此操作,而无需进行任何字符串到日期(或相反)的转换:

SELECT C_DAY,
       LEAST(
         ADD_MONTHS(
           TRUNC(SYSDATE, 'MM'),
           CASE WHEN c_day <= EXTRACT(DAY FROM SYSDATE) THEN 0 ELSE 1 END
         ) + c_day - 1,
         LAST_DAY(
           ADD_MONTHS(
             TRUNC(SYSDATE, 'MM'),
             CASE WHEN c_day <= EXTRACT(DAY FROM SYSDATE) THEN 0 ELSE 1 END
           )
         )
       ) AS new_field
FROM   my_table

其中,对于示例数据:

CREATE TABLE my_table(c_day) AS
  SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 31;

输出:
| C_日|新字段|
| - ------|- ------|
| 1个|2023年2月1日00时00分|
| 第二章|2023年2月2日00时00分|
| 三个|2023年2月3日00时00分|
| 四个|2023年2月4日00时00分|
| 五个|2023年2月5日00时00分|
| 六个|2023年2月6日00时00分|
| 七|2023年2月7日00时00分|
| 八个|2023年2月8日00时00分|
| 九|2023年3月9日00时00分|
| 十个|2023年3月10日00时00分|
| 十一|2023年3月11日00时00分|
| 十二|2023年3月12日00时00分|
| 十三|2023年3月13日00时00分|
| 十四|2023年3月14日00时00分|
| 十五|2023年3月15日00时00分|
| 十六|2023年3月16日00时00分|
| 十七|2023年3月17日00时00分|
| 十八|2023年3月18日00时00分|
| 十九|2023年3月19日00时00分|
| 二十个|2023年3月20日00时00分|
| 二十一|2023年3月21日00时00分|
| 二十二|2023年3月22日00时00分|
| 二十三|2023年3月23日00时00分|
| 二十四|2023年3月24日00时00分|
| 二十五|2023年3月25日00时00分|
| 二十六|2023年3月26日00时00分|
| 二十七|2023年3月27日00时00分|
| 二十八|2023年3月28日00时00分|
| 二十九|2023年3月29日00时00分|
| 三十|2023年3月30日00时00分|
| 三十一|2023年3月31日00时00分|
fiddle

kpbpu008

kpbpu0082#

这里有一个选择:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> WITH
  2     my_table (c_day)
  3     AS
  4        (SELECT 14 FROM DUAL
  5         UNION ALL
  6         SELECT 5 FROM DUAL
  7         UNION ALL
  8         SELECT 30 FROM DUAL)
  9  SELECT c_day,
 10         TO_DATE (
 11               LPAD (LEAST (c_day, TO_CHAR (LAST_DAY (SYSDATE), 'dd')), 2, '0')
 12            || '.'
 13            || TO_CHAR (
 14                  CASE
 15                     WHEN c_day < TO_CHAR (SYSDATE, 'dd')
 16                     THEN
 17                        ADD_MONTHS (SYSDATE, 1)
 18                     ELSE
 19                        SYSDATE
 20                  END,
 21                  'mm.yyyy'),
 22            'dd.mm.yyyy') AS result
 23    FROM my_table;

     C_DAY RESULT
---------- ----------
        14 14.02.2023
         5 05.03.2023
        30 28.02.2023

SQL>
e5nqia27

e5nqia273#

就我对你的问题的理解,一个解决办法可能是这样的

SELECT 
   C_DAY,
   CASE
     WHEN C_DAY >= TO_CHAR(SYSDATE, 'DD') THEN 
       ADD_MONTHS(TO_DATE(TO_CHAR(SYSDATE, 'YYYY-MM-')||C_DAY , 'YYYY-MM-DD'), 1)
     WHEN C_DAY < TO_CHAR(SYSDATE, 'DD') THEN
       TO_DATE(TO_CHAR(SYSDATE, 'YYYY-MM-')||C_DAY , 'YYYY-MM-DD')
   END AS new_field
FROM my_table

ADD_MONTHS函数的工作原理如下:
如果date是该月的最后一天,或者结果月的天数少于date的天部分,则结果为结果月的最后一天。否则,结果的天部分与date相同。

相关问题