I wasn’t sure how to title this question, but I’ve got an Oracle table that has a column for each day of the week. These represent the days a business is open. The values in these columns is either ‘Y’ or ‘N’. This is how the table was setup years ago and I am unable to change it.
ID | MONDAY | TUESDAY | WEDNESDAY | THURSDAY | FRIDAY | SATURDAY | SUNDAY 1 Y Y Y Y Y N N 2 N Y Y Y Y Y N
I need to be able to query this table and get results like the following, but am not sure where to even start.
ID | DAYS_OPEN 1 MONDAY - FRIDAY 2 TUESDAY - SATURDAY
Is this even possible in a query or will I need to use a function? If a function would make it easier, I’d be fine with that solution as well.
Advertisement
Answer
Found easier solution:
replace( trim( '.' from replace(replace(replace(replace(replace(replace(replace( regexp_replace( decode(MONDAY ,'Y','1','.') || decode(TUESDAY ,'Y','2','.') || decode(WEDNESDAY ,'Y','3','.') || decode(THURSDAY ,'Y','4','.') || decode(FRIDAY ,'Y','5','.') || decode(SATURDAY ,'Y','6','.') || decode(SUNDAY ,'Y','7','.') ,'(d)d*(d)','1-2') ,'1','MONDAY') ,'2','TUESDAY') ,'3','WEDNESDAY') ,'4','THURSDAY') ,'5','FRIDAY') ,'6','SATURDAY') ,'7','SUNDAY') ),'.',',')
Full example:
with t(ID, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) as ( select 1,'Y', 'Y', 'Y', 'Y', 'Y' ,'N', 'N' from dual union all select 2,'N', 'Y', 'Y', 'Y', 'Y' ,'Y', 'N' from dual union all select 3,'Y', 'N', 'Y', 'Y', 'N' ,'Y', 'Y' from dual ) select id ,replace( trim( '.' from replace(replace(replace(replace(replace(replace(replace( regexp_replace( decode(MONDAY ,'Y','1','.') || decode(TUESDAY ,'Y','2','.') || decode(WEDNESDAY ,'Y','3','.') || decode(THURSDAY ,'Y','4','.') || decode(FRIDAY ,'Y','5','.') || decode(SATURDAY ,'Y','6','.') || decode(SUNDAY ,'Y','7','.') ,'(d)d*(d)','1-2') ,'1','MONDAY') ,'2','TUESDAY') ,'3','WEDNESDAY') ,'4','THURSDAY') ,'5','FRIDAY') ,'6','SATURDAY') ,'7','SUNDAY') ),'.',',') as sch from t;
Result:
ID SCH ---------- ------------------------------------------------------------ 1 MONDAY-FRIDAY 2 TUESDAY-SATURDAY 3 MONDAY,WEDNESDAY-THURSDAY,SATURDAY-SUNDAY
Edit: expanding on the original answer to apply the same process to months of the year. I had to wrap the month number in square brackets in the decode. Then in the regexp_replace, I specified a non-matching list (period and whitespace).
Here’s the full example:
with t(ID, JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER ) as ( select 1,'Y', 'Y', 'Y', 'Y', 'Y' ,'N', 'N', 'Y','Y','Y','Y','Y' from dual union all select 2,'Y', 'Y', 'Y', 'Y', 'N' ,'N', 'N', 'N','Y','Y','Y','Y' from dual union all select 3,'N', 'N', 'Y', 'N', 'N' ,'Y', 'Y', 'N','N','N','Y','N' from dual union all select 4,'Y', 'N', 'Y', 'N', 'Y' ,'N', 'Y', 'N','Y','N','Y','N' from dual ) select id, regexp_replace( trim( '.' from replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace( regexp_replace( decode(JANUARY ,'Y','01','.') || decode(FEBRUARY ,'Y','02','.') || decode(MARCH ,'Y','03','.') || decode(APRIL ,'Y','04','.') || decode(MAY ,'Y','05','.') || decode(JUNE ,'Y','06','.') || decode(JULY ,'Y','07','.') || decode(AUGUST ,'Y','08','.')|| decode(SEPTEMBER ,'Y','09','.')|| decode(OCTOBER ,'Y','10','.')|| decode(NOVEMBER ,'Y','11','.')|| decode(DECEMBER ,'Y','12','.') ,'(dd)d*(dd)','1-2') ,'01','Jan') ,'02','Feb') ,'03','Mar') ,'04','Apr') ,'05','May') ,'06','Jun') ,'07','Jul') ,'08','Aug') ,'09','Sep') ,'10','Oct') ,'11','Nov') ,'12','Dec') ) ,'.+',', ') MNTHS from t;
and the results:
ID MNTHS 1 Jan-May, Aug-Dec 2 Jan-Apr, Sep-Dec 3 Mar, Jun-Jul, Nov 4 Jan, Mar, May, Jul, Sep, Nov