For "2012-07-12", how can I get the start of the week, i.e., "2012-07-08", and start of the month, i.e., "2012-07-01"?
-
how are you inserting the data? from a stored proc? from a program? are you wanting to insert the data "rounded" or "round" the data when you return it from the DB? – Borophyll Jul 12 '12 at 22:07
-
The data are already there with the full date. For some queries, I want to round the date. – DrXCheng Jul 12 '12 at 22:11
-
Duplicate (day of week): http://stackoverflow.com/questions/6944055/how-do-i-get-the-first-day-of-the-week-of-a-date-in-mysql – pilcrow Jul 12 '12 at 22:58
-
Duplicate (day of month): http://stackoverflow.com/questions/3298288/how-to-get-first-day-of-every-corresponding-month-in-mysql – pilcrow Jul 12 '12 at 23:00
5 Answers
First day of the month:
SELECT DATE_FORMAT('2007-07-12', '%Y-%m-01');
output: 2007-07-01
First day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFWEEK('2007-07-12')-1 DAY);
output: 2007-07-08
MySQL reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add

- 1,099
- 2
- 15
- 24
-
1
-
Noting that this truncates to Sunday as the start of the week, unlike postgres, which truncates to Mondays. – Oliver Bock Feb 17 '23 at 07:06
Same answer as Borophyll's, but I have changed the behavior of the first day of the month to return a date, not just a string which avoids date formatting/parsing mentioned in user151220's answer.
First day of the month:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFMONTH('2007-07-12') - 1 DAY);
output: 2007-07-01
First day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFWEEK('2007-07-12') - 1 DAY);
output: 2007-07-08
MySQL reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
For those who need Monday as the first day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL WEEKDAY('2007-07-12') DAY);
output: 2007-07-09
This relies on the WEEKDAY function, which starts with Monday instead of DAYOFWEEK, which starts with Sunday.

- 448
- 3
- 9
The DATE_FORMAT reply from Borophyll is very good, but gives a string rather than a date. So can't be compared easily.
If you need to use this as a comparison to a date field, use str_to_date to reverse it back to date rather than string.
select x from y where date >= str_to_date( DATE_FORMAT(now()-interval 12 month,'Y-%m-01'), '%Y-%m-%d')
If you are (say) looking at 12 months sales figures, but you want to always start off from the 1st of a month.

- 1,373
- 10
- 7
This will work if you want to just code it and forget about it, it will use datetime now and always return MTD results-
where date_completed between date_sub(date(now()), INTERVAL dayofmonth(now()) -1 day) and now()

- 51
- 2