I have a schedule table in mysql. I want to fetch first day and last day of the table as per country code.
Table
COUNTRY_CODE | IS_WORKING | FROM_TIME | END_TIME | DAY |
---|---|---|---|---|
IN | no | NULL | NULL | Sunday |
IN | yes | 09:00:00 | 18:00:00 | Monday |
IN | yes | 09:00:00 | 18:00:00 | Tuesday |
IN | yes | 09:00:00 | 18:00:00 | Wednesday |
IN | yes | 09:00:00 | 18:00:00 | Thursday |
IN | yes | 09:00:00 | 18:00:00 | Friday |
IN | no | NULL | NULL | Saturday |
UAE | yes | 10:00:00 | 19:00:00 | Sunday |
UAE | yes | 10:00:00 | 19:00:00 | Monday |
UAE | yes | 10:00:00 | 19:00:00 | Tuesday |
UAE | yes | 10:00:00 | 19:00:00 | Wednesday |
UAE | yes | 10:00:00 | 19:00:00 | Thursday |
UAE | no | NULL | NULL | Friday |
UAE | no | NULL | NULL | Saturday |
UK | yes | 09:00:00 | 18:00:00 | Sunday |
UK | yes | 09:00:00 | 18:00:00 | Monday |
UK | yes | 09:00:00 | 18:00:00 | Tuesday |
UK | yes | 09:00:00 | 18:00:00 | Wednesday |
UK | yes | 09:00:00 | 18:00:00 | Thursday |
UK | yes | 09:00:00 | 18:00:00 | Friday |
UK | no | NULL | NULL | Saturday |
I want result as per below :
COUNTRY_CODE | START_WORKING_DAY | END_WORKING_DAY |
---|---|---|
IN | Monday | Friday |
UAE | Sunday | Thursday |
UK | Sunday | Friday |
CodePudding user response:
I think this is simply:
select COUNTRY_CODE,
dayname(min(str_to_date(concat(197001,DAY),"%X%V%W"))) start_working_day,
dayname(max(str_to_date(concat(197001,DAY),"%X%V%W"))) end_working_day
from test
where IS_WORKING="yes"
group by 1
CodePudding user response:
Below solution maybe it can be simplified a little bit, but I can't think a better solution right now.
I have used twice row number and order by case including Sunday as first day and Saturday as last , in this way you can unique identify rows.
with cte as
( select *, row_number() over( partition by COUNTRY_CODE order by
CASE
WHEN Day = 'Sunday' THEN 1
WHEN Day = 'Monday' THEN 2
WHEN Day = 'Tuesday' THEN 3
WHEN Day = 'Wednesday' THEN 4
WHEN Day = 'Thursday' THEN 5
WHEN Day = 'Friday' THEN 6
WHEN Day = 'Saturday' THEN 7
END ASC ) as min_row_num,
row_number() over(partition by COUNTRY_CODE order by
CASE
WHEN Day = 'Sunday' THEN 1
WHEN Day = 'Monday' THEN 2
WHEN Day = 'Tuesday' THEN 3
WHEN Day = 'Wednesday' THEN 4
WHEN Day = 'Thursday' THEN 5
WHEN Day = 'Friday' THEN 6
WHEN Day = 'Saturday' THEN 7
END DESC) as max_row_num
from test
where IS_WORKING='yes'
) select c2.COUNTRY_CODE, START_WORKING_DAY,END_WORKING_DAY
from ( select COUNTRY_CODE,min(DAY) as END_WORKING_DAY
from cte
where max_row_num = (select min(max_row_num) from cte)
group by COUNTRY_CODE
) as c1
inner join
( select COUNTRY_CODE,min(DAY) as START_WORKING_DAY
from cte
where min_row_num = (select min(min_row_num) from cte)
group by COUNTRY_CODE
) as c2 on c1.COUNTRY_CODE=c2.COUNTRY_CODE
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f9100085f28ce84195615c7add66d0e2