I have a table PatientAppointment . There is only 2 columns AppointmentDateTime and Duration which stores date and total hr or minutes for which that particular patient had his appointment. Let us assume there is only one patient for now. I'm facing issues with partitioning. Here is the table:
+---------------------+-----------------+
| AppointmentDateTime | Duration |
+---------------------+-----------------+
| 2020-05-28 | 30 min |
| 2020-05-29 | 30 min |
| 2020-05-30 | 1 hour |
| 2020-06-03 | 1 hour |
| 2020-06-05 | 1 hour 30 min |
| 2020-07-21 | 1 hour 30 min |
| 2020-07-22 | 1 hour |
| 2020-07-28 | 30 min |
+---------------------+-----------------+
Here is the query. I'm first converting duration to minutes in integer like 30, 60, 90 so that I can sum them up. Then I've to partition them month wise. It should look like db<>fiddle . This works on fiddle.
select
sum(((case when duration like '% hour%' then substring_index(duration, ' hour', 1) * 60 else 0 end) +
(case when duration like '%min%' then substring_index(substring_index(duration, ' min', 1), ' ', -1) + 0 else 0 end))) over (partition by date_format(pa.AppointmentDateTime, '%Y-%m') order by pa.AppointmentDateTime) total
from PatientAppointment pa
This works on fiddle. But gives error on my local:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(partition by date_format(pa.AppointmentDateTime, '%Y-%m') order by pa.Appointme' at line 3
My local version are:
innodb_version 5.7.26, protocol_version 10, tls_version TLSv1,TLSv1.1,TLSv1.2 version 5.7.26-log
Please help me what to do now.
Cumulative sum using UDV:
select
dateOfCheckup,
duration,
-- use intermediate variable @cur_dur for not calculate this value twice
@cur_dur := ((case when duration like '% hour%' then substring_index(duration, ' hour', 1) * 60 else 0 end) +
(case when duration like '%min%' then substring_index(substring_index(duration, ' min', 1), ' ', -1) + 0 else 0 end)) as minutes,
-- check does current @year_month is equal to previous, continue or restart @cum_sum
CASE WHEN @year_month = date_format(dateOfCheckup, '%Y-%m')
THEN @cum_sum := @cum_sum + @cur_dur
ELSE @cum_sum := @cur_dur
END total,
-- store current @year_month for to use with next row
@year_month := date_format(dateOfCheckup, '%Y-%m') monthOfCheckup
from patient,
-- initialize variables which will be used
(SELECT @year_month:='', @cum_sum:=0, @cur_dur:=0) variables
-- the rows must be processed in definite order
ORDER BY dateOfCheckup
Output columns order is critical (the calulations in output columns in a row are performed strictly in the order in which they're written). But it doesn't matter if this example is used as a subquery or the output data is accessed by column names.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.