All date format in European (yyyy-mm-dd).
I am trying find the corresponding start date for a week reported by the weekofyear(this is, week starting on Monday).
set @date0 ='2012-12-31';
set @date1 ='2013-01-01';
select weekofyear(@date0), weekofyear(@date1);
> 1, 1
SQL Fidle 1 This is, both dates are in the first week of 2013. However, if I try to extract the year and weekofyear I will get different results (which means I need to find a different strategy):
set @date0 ='2012-12-31';
select year(@date0), weekofyear(@date0);
>2012,1
set @date1 ='2013-01-01';
select year(@date1), weekofyear(@date1);
>2013,1
SQl Fidle 2 If I manually consult the calender I can see to which year they belong (2013).
this big case will output the week start date
set @date1 ='2012-01-01';
select
case when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 1 day)) then @date1
when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 2 day)) then date_sub(@date1 , interval 1 day)
when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 3 day)) then date_sub(@date1 , interval 2 day)
when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 4 day)) then date_sub(@date1 , interval 3 day)
when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 5 day)) then date_sub(@date1 , interval 4 day)
when weekofyear(@date1) <> weekofyear(date_sub(@date1 , interval 6 day)) then date_sub(@date1 , interval 6 day)
else date_sub(@date1 , interval 6 day) end as week_start_date;
>2011-12-26
and this big case will also generate the combo year-week
set @date1 ='2012-12-31';
select
case when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 1 day)) then concat(year(@date1),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 2 day)) then concat(year(date_add(@date1 , interval 1 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 3 day)) then concat(year(date_add(@date1 , interval 2 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 4 day)) then concat(year(date_add(@date1 , interval 3 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 5 day)) then concat(year(date_add(@date1 , interval 4 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
when weekofyear(@date1) <> weekofyear(date_add(@date1 , interval 6 day)) then concat(year(date_add(@date1 , interval 5 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1))
else concat(year(date_add(@date1 , interval 6 day)),'-', if(weekofyear(@date1) < 10, '0','') ,weekofyear(@date1)) end as week_of_year;
> 2013-01
Now i either need to find an more elegant way of do it, or find a suitable strategy to include this in the group by condition. I was thinking in add an extra column to the table being grouped and -- after add an index --, group by week_of_year or by the week_start_date.
Does someone experienced have a better idea/strategy?
Notes: this is to be used in a database with over half million users, to Analise a certain action they perform and the group by condition will take other parameters (such as, but not limited to, demographics).