Stored procedure to list all weeks between two dates - mysql

I've searched but could not find a solution on how to list the weeks inbetween two dates.
I've found solutions that lists out all the days in the month between two dates:
select * from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2012-02-10' and '2012-02-15'
But nothing lists out the weeks as a 7 day week format, per below:
How would you do this?
Week Start: 2015-02-01 - Week End: 2015-02-07
Week Start: 2015-02-08 - Week End: 2015-02-14
Week Start: 2015-02-15 - Week End: 2015-02-21
Week Start: 2015-02-22 - Week End: 2015-02-28

You could select all days and filter on the first day of the week (date_format(selected_date, '%w') = 0):
select selected_date, date_add(selected_date, INTERVAL 6 DAY)
from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date
from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2015-02-01' and '2015-02-28'
AND date_format(selected_date, '%w') = 0
SQLFIDDLE: http://sqlfiddle.com/#!2/7bc0e/52
You could use
AND DAYOFWEEK(selected_date) = 1
instead of
date_format(selected_date, '%w') = 0
I think it is a little bit more readable: http://sqlfiddle.com/#!2/7bc0e/54

Related

How to Get List of weeks between the given date range?

I want week list with week number, week start date and end date between two dates. Let me give you an example,
If I am passing start date as 2019-12-11 and end date as 2019-12-25, then expected output should look like below:
Week Number | Week start date | Week end date
W1 2019-12-11 2019-12-14
W2 2019-12-15 2019-12-21
W3 2019-12-22 2019-12-25
I have tried using below query but I got output like
Week start date | Week end date
2019-12-15 2019-12-21
2019-12-22 2019-12-28
select start_date, date_add(start_date, INTERVAL 6 DAY) as end_date
from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) start_date
from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where start_date between '2019-12-11' and '2019-12-25'
AND date_format(start_date, '%w') = 0
You can use the following solution using WEEK function and ROW_NUMBER:
-- calendar table: https://stackoverflow.com/a/45992247/3840840
SELECT CONCAT('W', ROW_NUMBER() OVER (ORDER BY WEEK(start_date))) AS `Week Number`,
MIN(start_date) AS `Week start date`, MAX(start_date) AS `Week end date`
FROM (
SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS start_date
FROM
(SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
) v
WHERE start_date BETWEEN '2019-12-11' AND '2019-12-25'
GROUP BY WEEK(start_date)
ORDER BY WEEK(start_date)
By using WEEK you don't have to calculate the weeks yourself. MySQL can detect the weeks. With WEEK you can get the week number of a date value. You can group by this week number to get the rows for every week. With MIN and MAX on the date value you get the first and last date of each week.
With ROW_NUMBER you can add a row number to your result. This function is available since MySQL 8.0. On earlier versions of MySQL you can use a solution like the following:
SELECT CONCAT('W', #row_number:=#row_number+1) AS `Week Number`,
MIN(start_date) AS `Week start date`, MAX(start_date) AS `Week end date`
FROM (
SELECT ADDDATE('1970-01-01', t4 * 10000 + t3 * 1000 + t2 * 100 + t1 * 10 + t0) AS start_date
FROM
(SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
ORDER BY start_date
) v, (SELECT #row_number:=0) rn
WHERE start_date BETWEEN '2019-12-11' AND '2019-12-25'
GROUP BY WEEK(start_date)
ORDER BY WEEK(start_date)
demo on dbfiddle.uk

Select every other day of week using SQL (MySQL)

The goal is to return a set of dates that correspond to the day of week requested.
For example: every other Monday between 2018-08-13 and 2018-12-31.
The following statement returns all dates and works great
select * from
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where DATES between '2018-08-13' and '2018-12-31'
and dayname(DATES) ='MONDAY'
So to return every other MONDAY I added the following
HAVING DATES % 2 = 0
I assumed that by taking MOD of dates it would, in this case return every MONDAY that met this criteria. Well it does not work. I've tried all sorts of combos but not getting it.
Any ideas?
Dates are a complex data structure and the details of how they are stored and manipulated vary between DBMSs. Most often you can't treat them as numeric data types as you are trying to do here. Instead you should calculate the number of days between the date of interest and a fixed date then you can take the modulus of that number: for example:
select * from
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where DATES between '2018-08-13' and '2019-01-31'
and dayname(DATES) ='MONDAY'
and datediff(dates,'2018-08-13') % 2 = 0
order by dates
Alternatively since every other Monday is 14 days apart you could use modulus 14 and drop the dayname(DATES) ='MONDAY' predicate:
select * from
(select adddate('2010-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) DATES from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where DATES between '2018-08-13' and '2019-01-31'
and datediff(dates,'2018-08-13') % 14 = 0
order by dates
This can be made to work with a few little modifications as follows:
SELECT * FROM
(
SELECT ADDDARE('1970-01-01', t4*10000 + t3*1000 + t2*100 + t1*10 + t0) selected_date FROM
(SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3,
(SELECT 0 t4 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t4
) v
WHERE
selected_date between '2018-08-08' AND '2018-10-19'
AND DAYOFWEEK(selected_date) = 2
AND WEEK(selected_date) % 2 = WEEK('2018-08-08') % 2
The idea is that it will include the Monday of the week that the selection period begins from. So, it doesn't matter whether the starting week is odd or even, you'd always get alternate Mondays without having to worry about specifying 0 or 1 for the result of modulo operation.

I cannot find the table I created in the schema

I have a questions when I try to create a table in mysql.
The syntax is below:
create table abc as
(select * from
(select adddate('2010-01-01',t5.i*100000 +t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t5) v
where selected_date between '2010-01-01' and '2020-12-31');
It seems that I create the table successfully, but I cannot find this table in the tables list or even in the schema.
Could someone who has expertise in SQL help me check the syntax?

Display dates based on week() result, except Sunday

So we all know that we can get the week number of a date by using the week() function. My question is how to display the dates of that particular week, except the Sunday date?
To illustrate..
Based from the above example, what I want to display is..
2009-05-17
2009-05-18
2009-05-19
2009-05-20
2009-05-21
2009-05-22
How do I query this?
SET #GivenDate ='2016-05-27';
SET #YearNum = YEAR(#GivenDate);
SET #WeekNum=WEEK(#GivenDate);
select selected_date,weekday(selected_date) AS WeeKDate
from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where YEAR(selected_date)=#YearNum
AND WEEK(selected_date)=#WeekNum
AND WEEKDAY(selected_date)<> 6;

How to get list of dates between two dates in mysql select query [duplicate]

This question already has answers here:
Get a list of dates between two dates
(23 answers)
Closed 9 years ago.
I want list of dates lies between two dates by select query. For example:
If i give '2012-02-10' and '2012-02-15' I need the result.
date
----------
2012-02-10
2012-02-11
2012-02-12
2012-02-13
2012-02-14
2012-02-15
How can i get?
Try:
select * from
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) selected_date from
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2012-02-10' and '2012-02-15'
-for date ranges up to nearly 300 years in the future.
[Corrected following a suggested edit by UrvishAtSynapse.]
set #i = -1;
SELECT DATE(ADDDATE('2012-02-10', INTERVAL #i:=#i+1 DAY)) AS date FROM `table`
HAVING
#i < DATEDIFF('2012-02-15', '2012-02-10')
This will return your result set exactly as prescribed. This query only requires you change the two different dates in datediff and adddate.
The accepted answer didn't work for me in MySQL 5.5.
I updated the query to work for me:
select * from
(select adddate('1970-01-01',t4*10000 + t3*1000 + t2*100 + t1*10 + t0) selected_date from
(select 0 t0 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0,
(select 0 t1 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1,
(select 0 t2 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2,
(select 0 t3 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3,
(select 0 t4 union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v
where selected_date between '2012-02-10' and '2012-02-15'
Take a look at this post : Get a list of dates between two dates
Check the stored procedure that Ron Savage did, this seems to correspond to what you need !
You can create a table containing all the dates you might ever need to use:
date
2000-01-01
2000-01-02
2000-01-03
...etc..
2100-12-30
2100-12-31
Then query that table as follows:
SELECT date
FROM dates
WHERE date BETWEEN '2012-02-10' AND '2012-02-15'
SELECT * FROM tablexxx WHERE datecol BETWEEN '2012-02-10' AND '2012-02-15';