I have a table where it has some name and dateofbirth.
Refence data:
ABC, 1990-11-23
BCD, 1998-10-21
CDE, 1997-05-02
DEF, 2000-10-15
EFG, 1999-01-10
FGH, 1987-01-15
GHI, 1989-12-19
HIJ, 1986-12-09
I need a SQL query where I need to get the birthday celebration dates that is going to happen during the next 60 days ordered by celebration dates.
This is the query that I used till now.
SELECT *
FROM `friends`
WHERE ( DATE_FORMAT(`dob`, '%m%d') >= DATE_FORMAT(CURDATE(), '%m%d')
AND DATE_FORMAT(`dob`, '%m%d') <= DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 60 DAY), '%m%d')
ORDER BY DATE_FORMAT(`dob`, '%m%d');
It works ok if it runs during Jan to Oct. During November and December, the condition DATE_FORMAT(dob, '%m%d') <= DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 60 DAY), '%m%d') cannot apply. For example, the resulting comparison will be like 1209 < 0131 and fails.
The result that I expect to get when executed on Dec 2, 2022 is
HIJ, 1986-12-09
GHI, 1989-12-19
EFG, 1999-01-10
FGH, 1987-01-15
How do I do this in one single query?
The thread mentioned in the comment to your question uses things like adding 365.25 days to get this to work. I think this solution might be more reliable.
You can construct this years' birthday by extracting the month and day from the date of birth, and concatenating the current year to it using STR_TO_DATE.
Then you can check using a CASE statement if this years' birthday has already passed, in which case you add a year to that birthday, because that will be the next birthday for name. Then you can check if the result of that CASE statement is BETWEEN today and 60 days from now.
I used a CTE to make it clearer to read. DBfiddle here.
WITH cte as (
SELECT
-- First determine this years (year of current date) birthday
-- by constructing it from the current year, month of birth and day of birth
STR_TO_DATE(
CONCAT(YEAR(CURDATE()),'-', MONTH(dob), '-', DAY(dob)),
'%Y-%m-%d') AS this_years_birthday,
name,
dob
FROM friends
)
SELECT cte.name, cte.dob
FROM cte
WHERE
-- If the birthday is still in this year
-- Use this years' birthday
-- else add a year to this years' birthday
-- Then filter it to be between today and 60 days from now
CASE WHEN this_years_birthday >= CURDATE()
THEN this_years_birthday
ELSE DATE_ADD(this_years_birthday, INTERVAL 1 YEAR) END
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 60 DAY)
ORDER BY MONTH(cte.dob) DESC
name
dob
GHI
1989-12-19
HIJ
1986-12-09
EFG
1999-01-10
FGH
1987-01-15
I have table months:
id name
=============
1 January
2 February
3 March
.. ........
I have the year stored in a variable:
SET #year = YEAR(CURDATE());
I now want 2 new columns: start_date and end_date - both of these columns will contain the start date and end date of the month based on the id and #year variable. This will be in the standard MySQL date column format. Currently I have this:
CONCAT(#year, '-', LPAD(months.id, 2, '0'), '-', '01') AS start_date,
CONCAT(#year, '-', LPAD(months.id, 2, '0'), '-', '31') AS end_date
This does work but is there a better/cleaner way? Is there a way to automatically get the actual last day of the month?
You can get the first day of the year using date() and strings. The rest can be done using date functions and operators:
select m.*,
date(concat(year(curdate()), '-01-01')) + interval (id - 1) month as month_start,
last_day(date(concat(year(curdate()), '-01-01')) + interval (id - 1) month) as month_end
from months m;
Here is a small db<>fiddle.
I have a table with rows of dates,
I need to get rows for one year:
SELECT DATE_FORMAT(cal_date, '%e %M') as cal_date, price_client,
price_owner, description FROM table WHERE cal_date <
DATE_ADD('2017-09-13' , INTERVAL 1 year)
The result of this query are date rows with dates from 1 September 2017 until 12 September 2018.
I would like the result from 13 September 2017 until 12 September 2018.
Updated, This is the correct query, works like I wanted:
WHERE cal_date >= '2017-09-13' and cal_date < DATE_ADD('2017-09-13' ,
INTERVAL 1 year)
for a generic format based on curdate() you could use
SELECT
DATE_FORMAT(cal_date, '%e %M') as cal_date
, price_client
, price_owner
, description
FROM table WHERE cal_date <
DATE_ADD(DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), interval 30 day), interval 1 day) ,
INTERVAL 1 year)
Seems to work once you account for cal_date>= same date
you handled < future date but you didn't handle > or >= current date. As it stands you will always return all records older than 1 year from today. you have no lower boundary defined.
DEMO: http://rextester.com/WDXHE5921
SELECT DATE_FORMAT(cal_date, '%e %M%Y') as cal_date, price_client,
price_owner, description
FROM table
WHERE cal_date < DATE_ADD('2017-09-13' , INTERVAL 1 year)
and cal_date >= '2017-09-13';
This question would have benefited from talking to the duck first
I need to select data from MySQL database between the 1st day of the current month and current day.
select*from table_name
where date between "1st day of current month" and "current day"
Can someone provide working example of this query?
select * from table_name
where (date between DATE_ADD(LAST_DAY(DATE_SUB(CURDATE(), interval 30 day), interval 1 day) AND CURDATE() )
Or better :
select * from table_name
where (date between DATE_FORMAT(NOW() ,'%Y-%m-01') AND NOW() )
I was looking for a similar query where I needed to use the first day of a month in my query.
The last_day function didn't work for me but DAYOFMONTH came in handy.
So if anyone is looking for the same issue, the following code returns the date for first day of the current month.
SELECT DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY);
Comparing a date column with the first day of the month :
select * from table_name where date between
DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY) and CURRENT_DATE
select * from table_name
where `date` between curdate() - dayofmonth(curdate()) + 1
and curdate()
SQLFiddle example
I have used the following query. It has worked great for me in the past.
select date(now()) - interval day(now()) day + interval 1 day
try this :
SET #StartDate = DATE_SUB(DATE(NOW()),INTERVAL (DAY(NOW())-1) DAY);
SET #EndDate = ADDDATE(CURDATE(),1);
select * from table where (date >= #StartDate and date < #EndDate);
Complete solution for mysql current month and current year, which makes use of indexing properly as well :)
-- Current month
SELECT id, timestampfield
FROM table1
WHERE timestampfield >= DATE_SUB(CURRENT_DATE, INTERVAL DAYOFMONTH(CURRENT_DATE)-1 DAY)
AND timestampfield <= LAST_DAY(CURRENT_DATE);
-- Current year
SELECT id, timestampfield
FROM table1
WHERE timestampfield >= DATE_SUB(CURRENT_DATE, INTERVAL DAYOFYEAR(CURRENT_DATE)-1 DAY)
AND timestampfield <= LAST_DAY(CURRENT_DATE);
select * from table
where date between
(date_add (CURRENT_DATE, INTERVAL(1 - DAYOFMonth(CURRENT_DATE)) day)) and current_date;
select * from <table>
where <dateValue> between last_day(curdate() - interval 1 month + interval 1 day)
and curdate();
I found myself here after needing this same query for some Business Intelligence Queries I'm running on an e-commerce store. I wanted to add my solution as it may be helpful to others.
set #firstOfLastLastMonth = DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH)))-1 DAY);
set #lastOfLastLastMonth = LAST_DAY(DATE_ADD(NOW(), INTERVAL -2 MONTH));
set #firstOfLastMonth = DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH)))-1 DAY);
set #lastOfLastMonth = LAST_DAY(DATE_ADD(NOW(), INTERVAL -1 MONTH));
set #firstOfMonth = DATE_ADD(#lastOfLastMonth, INTERVAL 1 DAY);
set #today = CURRENT_DATE;
Today is 2019-10-08 so the output looks like
#firstOfLastLastMonth = '2019-08-01'
#lastOfLastLastMonth = '2019-08-31'
#firstOfLastMonth = '2019-09-01'
#lastOfLastMonth = '2019-09-30'
#firstOfMonth = '2019-10-01'
#today = '2019-10-08'
A less orthodox approach might be
SELECT * FROM table_name
WHERE LEFT(table_name.date, 7) = LEFT(CURDATE(), 7)
AND table_name.date <= CURDATE();
as a date being between the first of a month and now is equivalent to a date being in this month, and before now. I do feel that this is a bit easier on the eyes than some other approaches, though.
SELECT date_sub(current_date(),interval dayofmonth(current_date())-1 day) as first_day_of_month;
I had some what similar requirement - to find first day of the month but based on year end month selected by user in their profile page.
Problem statement - find all the txns done by the user in his/her financial year. Financial year is determined using year end month value where month can be any valid month - 1 for Jan, 2 for Feb, 3 for Mar,....12 for Dec.
For some clients financial year ends on March and some observe it on December.
Scenarios - (Today is `08 Aug, 2018`)
1. If `financial year` ends on `July` then query should return `01 Aug 2018`.
2. If `financial year` ends on `December` then query should return `01 January 2018`.
3. If `financial year` ends on `March` then query should return `01 April 2018`.
4. If `financial year` ends on `September` then query should return `01 October 2017`.
And, finally below is the query. -
select #date := (case when ? >= month(now())
then date_format((subdate(subdate(now(), interval (12 - ? + month(now()) - 1) month), interval day(now()) - 2 day)) ,'%Y-%m-01')
else date_format((subdate(now(), interval month(now()) - ? - 1 month)), '%Y-%m-01') end)
where ? is year end month (values from 1 to 12).
The key here is to get the first day of the month. For that, there are several options. In terms of performance, our tests show that there isn't a significant difference between them - we wrote a whole blog article on the topic. Our findings show that what really matters is whether you need the result to be VARCHAR, DATETIME, or DATE.
The fastest solution to the real problem of getting the first day of the month returns VARCHAR:
SELECT CONCAT(LEFT(CURRENT_DATE, 7), '-01') AS first_day_of_month;
The second fastest solution gives a DATETIME result - this runs about 3x slower than the previous:
SELECT TIMESTAMP(CONCAT(LEFT(CURRENT_DATE, 7), '-01')) AS first_day_of_month;
The slowest solutions return DATE objects. Don't believe me? Run this SQL Fiddle and see for yourself 😊
In your case, since you need to compare the value with other DATE values in your table, it doesn't really matter what methodology you use because MySQL will do the conversion implicitly even if your formula doesn't return a DATE object.
So really, take your pick. Which is most readable for you? I'd pick the first since it's the shortest and arguably the simplest:
SELECT * FROM table_name
WHERE date BETWEEN CONCAT(LEFT(CURRENT_DATE, 7), '-01') AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN DATE(CONCAT(LEFT(CURRENT_DATE, 7), '-01')) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (LAST_DAY(CURRENT_DATE) + INTERVAL 1 DAY - INTERVAL 1 MONTH) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (DATE(CURRENT_DATE) - INTERVAL (DAYOFMONTH(CURRENT_DATE) - 1) DAY) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN (DATE(CURRENT_DATE) - INTERVAL (DAYOFMONTH(CURRENT_DATE)) DAY + INTERVAL 1 DAY) AND CURDATE;
SELECT * FROM table_name
WHERE date BETWEEN DATE_FORMAT(CURRENT_DATE,'%Y-%m-01') AND CURDATE;
I used this one
select DATE_ADD(DATE_SUB(LAST_DAY(now()), INTERVAL 1 MONTH),INTERVAL 1 day) first_day
,LAST_DAY(now()) last_day, date(now()) today_day
All the responses here have been way too complex. You know that the first of the current month is the current date but with 01 as the date. You can just use YEAR() and MONTH() to build the month date by inputting the NOW() method.
Here's the solution:
select * from table_name
where date between CONCAT_WS('-', YEAR( NOW() ), MONTH( NOW() ), '01') and DATE( NOW() )
CONCAT_WS() joins a series of strings with a separator (a dash in this case).
So if today is 2020-08-28, YEAR( NOW() ) = '2020' and MONTH( NOW() ) = '08' and then you just need to append '01' at the end.
Voila!
Get first date and last date from month and year.
select LAST_DAY(CONCAT(year,'.',month,'.','01')) as registerDate from user;
select date_add(date_add(LAST_DAY(end_date),interval 1 DAY),interval -1 MONTH) AS closingDate from user;
SET #date:='2012-07-11';
SELECT date_add(date_add(LAST_DAY(#date),interval 1 DAY),
interval -1 MONTH) AS first_day
I have a table with a column dedicated solely to DATETIME values (e.g. "2010-11-12 12:34:56"). I'm trying to figure out how to select all rows from the table where the month is the month after the current month, while also taking into account for year changes (that is, if the current month is December in 2010, I want to select all values that are dated January 2011).
I have a hard time figuring out how to do it. This is my current query for selecting all values for the remainder of the current month:
$query = "SELECT * FROM mytable WHERE uid = " . $_SESSION['uid'] . " AND EXTRACT(YEAR FROM NOW()) = EXTRACT(YEAR FROM date_time) AND EXTRACT(MONTH FROM NOW()) = EXTRACT(MONTH FROM date_time) AND EXTRACT(DAY FROM NOW()) < EXTRACT(DAY FROM date_time) ORDER BY date_time";
I tried using the guide at http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html (CURDATE and MOD), but I couldn't get it to work. :(
Any help is very appreciated!
... WHERE YEAR(date_time) = YEAR(DATE_ADD(NOW(), INTERVAL 1 MONTH))
AND MONTH(date_time) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH))
This one would be faster because it can utilize available indexes on the datetime field:
... WHERE date_time BETWEEN
DATE_SUB(DATE_ADD(NOW(), INTERVAL 1 MONTH),INTERVAL (DAY(NOW())-1) DAY)
AND
DATE_SUB(DATE_ADD(NOW(), INTERVAL 2 MONTH),INTERVAL (DAY(NOW())) DAY)