如何在不使用to_date,trunc和预定义的add_months函数的情况下获取上个月的第一个和最后一个日期

时间:2018-08-15 17:17:31

标签: oracle

我编写了以下代码,但没有得到预期的输出:

SQL> select TO_CHAR(TO_CHAR(sysdate,'MM')-1,'DD-MM-YYYY') AS PREV_MON_FIRST,
             TO_CHAR(TO_CHAR(sysdate,'MM'),'DD-MM-YYYY')-1 AS PREV_MON_LAST from dual;

select TO_CHAR(TO_CHAR(sysdate,'MM')-1,'DD-MM-YYYY') AS PREV_MON from dual
                                       *
ERROR at line 1:
ORA-01481: invalid number format model

正确的是缺少“ DD”和“ YYYY”值,但是当我尝试仅检索月份时,它也会显示相同的错误

5 个答案:

答案 0 :(得分:2)

您可以使用以下解决方案:

SELECT
    TRUNC(LAST_DAY(ADD_MONTHS(sysdate, -2))) + 1 AS first_date,
    TRUNC(LAST_DAY(ADD_MONTHS(sysdate, -1))) AS last_date
FROM dual

答案 1 :(得分:0)

如果TO_CHAR格式适合您的需要,仅使用YYYYMMDD选择上个月的第一天很容易:

SQL> select (to_char(sysdate, 'yyyymm') - 1) || '01' first_day
  2  from dual;

FIRST_DAY
------------------------------------------
20180701

SQL>

但是,最后一天-我不知道。


通常的实现方式有效,但涉及其他功能:

SQL> select trunc(add_months(sysdate, -1), 'mm') first_day,
  2         trunc(sysdate, 'mm') - 1 last_day
  3  from dual;

FIRST_DAY  LAST_DAY
---------- ----------
2018-07-01 2018-07-31

SQL>

答案 2 :(得分:0)

对于LAST_DAY,这里是不包含add_months,trunc,to_date的具有月份值的硬编码的查询

settingsObj: Handsontable.GridSettings = {
    data: [{id: 1, name: ('t'+ this.t1Title)},
           {id: 2, name: 'me'},
           {id: 3, name: 'me' }
    ],

答案 3 :(得分:0)

如果从字面上我回答您的问题,一个解决方案是

CREATE OR REPLACE FUNCTION MY_LAST_DAY RETURN TIMESTAMP AS
    next_run_date TIMESTAMP;
    return_date_after TIMESTAMP := SYSTIMESTAMP - INTERVAL '100' DAY;
BEGIN
    LOOP  
        DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=DAILY;INTERVAL=1;BYMONTHDAY=-1', NULL, return_date_after, next_run_date);
        EXIT WHEN EXTRACT(MONTH FROM next_run_date) = EXTRACT(MONTH FROM SYSTIMESTAMP);
        return_date_after := next_run_date;
    END LOOP;    
    RETURN return_date_after;
END;
/

CREATE OR REPLACE FUNCTION MY_FIRST_DAY RETURN TIMESTAMP AS
    next_run_date TIMESTAMP;
    return_date_after TIMESTAMP := SYSTIMESTAMP - INTERVAL '100' DAY;
BEGIN
    LOOP  
        DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING('FREQ=DAILY;INTERVAL=1;BYMONTHDAY=1', NULL, return_date_after, next_run_date);
        EXIT WHEN EXTRACT(MONTH FROM next_run_date) = EXTRACT(MONTH FROM SYSTIMESTAMP);
        return_date_after := next_run_date;
    END LOOP;    
    RETURN return_date_after;
END;
/

它不使用TO_DATE(或TO_TIMESTAMP),TRUNCADD_MONTHS来返回上个月的第一个和最后一个日期

但是我希望你同意你的问题很愚蠢。

答案 4 :(得分:0)

对于LAST_DAY,这里是不包含add_months,trunc,to_date的具有月份值的硬编码的查询

选择to_char(sysdate,'yyyy')||   to_char(sysdate,'mm')-1 ||   (1,3,5,7,8,10,12)中的to_char(sysdate,'mm')-1时的情况THEN 31       当to_char(sysdate,'mm')-1 in(4,6,9,11)THEN 30时       当mod(to_char(sysdate,'yyyy'),4)= 0并且to_char(sysdate,'mm')-1 = 2然后29       当mod(to_char(sysdate,'yyyy'),4)!= 0和to_char(sysdate,'mm')-1 = 2然后28   结束   从双重

用于处理1月和Le年的新查询:

选择解码(to_char(sysdate,'mm'),1,to_char(sysdate,'yyyy')-1,to_char(sysdate,'yyyy'))||   解码(to_char(sysdate,'mm'),1,12,to_char(sysdate,'mm')-1)||   在(1,3,5,7,8,10,0)中的to_char(sysdate,'mm')-1时的情况31        当to_char(sysdate,'mm')-1 in(4,6,9,11)然后30        当to_char(sysdate,'mm')-1 = 2 AND mod(to_char(sysdate,'yyyy'),4)!= 0 AND mod(to_char(sysdate,'yyyy'),400)!= 0然后29       其他28   结束   从双重