Different variations of this question have been asked before, but none for the use case that I'm looking for. I'd like to find the specific number of weekdays between two dates for each row of a MySQL table and then update a column of each row with the result of that operation. This is part of an ETL process, and I'd like to keep this in a stored procedure if at all possible.
Data
Dates are of DATE
type and I'd like to find the number of a specific because I have 7 day
columns that have a flag if a record occurs on that day of the week. Like this (1 is Monday):
day_1 | day_2 | day_3 | day_4 | day_5 | day_6 | day_7
----- | ----- | ----- | ----- | ----- | ----- | -----
0 | 1 | 0 | 1 | 1 | 0 | 1
Example Use Case
I'm doing this because I'm trying to find the frequency of rows for a timeframe that's not available in the input data (call it input
). So for a record that had start
and end
date values of 2016-01-01
and 2016-03-01
, I'd want to know how often that record would have occurred only from 2016-01-01
to 2016-01-31
, inclusive. I initially tried to do this by making a table that contained all datevalues for many years into the future like:
datevalue
---------
2016-01-01
2016-01-02
...
and then joining input
to that table on start_date
and end_date
and then aggregating up while counting the number of each day like this:
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 1 THEN 1 ELSE 0 END) * day_1 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 2 THEN 1 ELSE 0 END) * day_2 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 3 THEN 1 ELSE 0 END) * day_3 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 4 THEN 1 ELSE 0 END) * day_4 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 5 THEN 1 ELSE 0 END) * day_5 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 6 THEN 1 ELSE 0 END) * day_6 +
SUM(CASE WHEN WEEKDAY(B.datevalue) + 1 = 7 THEN 1 ELSE 0 END) * day_7 AS adj_total_frequency
That worked perfectly on a smaller dataset, but input
has > 30 million records, and when I tried running on that procedure it ran for 36 hours before I killed it.
Is there a more efficient way of doing this in MySQL?