sqloracle-sqldeveloper

Oracle SQL - Change CASE expression from months to specific dates (BETWEEN)


I am trying to convert an existing CASE expression that is looking at months and instead have it look at exact dates.

CASE
    WHEN reg_con * tagg_reading <60 and to_char(read_date,'mm') in ('06','07','08','09') then 'Y'
    WHEN reg_con * tagg_reading <90 and to_char(read_date,'mm') in ('01','02','03','04','05','10','11','12') then 'Y'
ELSE 'N'
END as Keep_Flag

My changes run, but the results are incorrect

CASE
   WHEN reg_con * tagg_reading <60 and to_char(read_date, 'MM-DD') BETWEEN '6-15' AND '10-15' then 'Y'
   WHEN reg_con * tagg_reading <90 and to_char(read_date, 'MM-DD') BETWEEN '10-16' AND '6-14' then 'Y'
ELSE 'N'
END as Keep_Flag

Thank for any help adjusting.

The results of the CASE expressions are used to filter the data in a WHERE statement

WHERE keep_flag = 'Y'

Solution

  • I tried reproducing your issue with the assumption read_date is in the format DD-MM-YY. Your query is comparing strings.

    You can use TO_DATE like so

    TO_DATE(TO_CHAR(read_date, 'MM-DD'), 'MM-DD') BETWEEN TO_DATE('06-15', 'MM-DD') AND TO_DATE('10-15', 'MM-DD') 
    

    For the second condition

    BETWEEN '10-16' AND '6-14'
    

    Do you intend to include dates between 16th October and 14th June or the other way round i,e dates between 14th June and 16th October.I assume you want to add dates between 16th October and 14th June since June to October is included in the first condition.

    AND (TO_CHAR(read_date, 'MM-DD') BETWEEN '10-16' AND '12-31' OR TO_CHAR(read_date, 'MM-DD') BETWEEN '01-01' AND '06-14') THEN 'Y'
    

    Fiddle

    Sample Input

    ID REG_CON TAGG_READING READ_DATE
    1 1 10 20-JUN-24
    2 4 20 10-APR-24
    3 4 30 15-AUG-24
    4 4 40 25-DEC-24
    5 3 50 05-OCT-24
    SELECT id, reg_con, tagg_reading, read_date,
    CASE
        WHEN reg_con * tagg_reading < 60 
             AND TO_CHAR(read_date, 'MM-DD') BETWEEN '06-15' AND '10-15' THEN 'Y'
        WHEN reg_con * tagg_reading < 90 
             AND (TO_CHAR(read_date, 'MM-DD') BETWEEN '10-16' AND '12-31' OR TO_CHAR(read_date, 'MM-DD') BETWEEN '01-01' AND '06-14') THEN 'Y'
        ELSE 'N'
    END AS Keep_Flag
    FROM test;
    

    Output

    ID REG_CON TAGG_READING READ_DATE KEEP_FLAG
    1 1 10 20-JUN-24 Y
    2 4 20 10-APR-24 Y
    3 4 30 15-AUG-24 N
    4 4 40 25-DEC-24 N
    5 3 50 05-OCT-24 N