Create a dynamic time range in sql - mysql

Is there a way to create a dynamic way to make a sql query that queries the data between the first day and the last day of every current month? I have a field called created and and I want to get the data where created is between the first day and the last day of the month.

Something like this will do it:
WHERE created BETWEEN DATE_FORMAT(Now(), '%Y-%M-01 00:00:00') AND DATE_FORMAT(DATE_ADD(DATE_ADD(Now(),INTERVAL 1 MONTH), INTERVAL -12 HOUR), '%Y-%M-%d 23:59:59')
It’s not pretty, but it gets the job done.

Is there a way to create a dynamic way to make a sql query that queries the data between the first day and the last day of every current month?
A simple method uses just date functions:
where created_at >= curdate() + interval (1 - day(curdate()) day and
created_at < (curdate() + interval (1 - day(curdate()) day) + interval 1 month
In addition to only using date arithmetic, this doesn't have an error of missing the last second of the month.

Related

SQL query: A view which gathers from today last month and 2 month in advance

I'm amending a current query which I run on a fairly regular basis for a membership team looking at recent expiries. The clause in that query is:
and date_expiry between '2019-11-01' and '2019-12-31'
The dates are expanded to cover a 2 month period.
What I'd like to do is to create this query as an excel view in which they can refresh as an when they want.
What I have so far and works to a degree* is the following:
and date_expiry between curdate()- interval 1 month and curdate()+ interval 3 month
However the issue many may have picked up on is that the above query gathers data from today 1 month previous (10/11/2019) and 3 months from today (10/02/2020).
So I've been searching around and the closest I've got was this:
and month(date_expiry) = month(current_date- interval 1 month ) and year(date_expiry)= year(curdate())
This works perfectly for collecting everything in the previous month (01/11/2019-31/11/2019) but I somehow need to add something similar to gather data data for the advanced months.
Help please!
The curdate() suggests MySQL. You can handle full dates as:
where date_expiry >= (curdate() - interval (1 - day(curdate())) day) - interval 1 month and
date_expiry < (curdate() - interval (1 - day(curdate())) day) + interval 1 month
This is convenient because it is index-friendly.
Try DATE_SUB for substraction and DATE_ADD for 2 months advanced
cek this query is this the day you want to cek?
you can change the interval if you want and change the NOW() with your custom date yourself.
to learn about interval check this link
SELECT DATE_SUB(DATE(CONCAT_WS('-', YEAR(NOW()) , MONTH(NOW()), 31)),INTERVAL 1 MONTH) AS lastdaymonthbefore,
DATE_ADD(DATE(NOW()),INTERVAL 2 MONTH) AS 2monthAdvanceFromToday
so you can edit your query like this
AND date_expiry BETWEEN DATE_SUB(DATE(CONCAT_WS('-', YEAR(NOW()) , MONTH(NOW()), 31)),INTERVAL 1 MONTH) AND DATE_ADD(DATE(NOW()),INTERVAL 2 MONTH)

date condition to retrieve data in a 24 hour time window mysql

I am using perl and DBI to query a mysql table. I need to retrieve all rows (aprox. 75,000 rows from 3 separate databases) within the past 24 hours, ideally between 12:00 am and 11:59 pm or 00:00:00 and 23:59:59.
I was using a WHERE date condition like this:
SELECT *
FROM table_name
WHERE insert_date >= DATE_SUB(NOW(), INTERVAL 1 DAY);
Then I would run my script at midnight using cron. This worked well enough, but due to a regular large volume of traffic at midnight and the size of the queries, the execution time scheduled with cron is now 3:00 am. I changed my sql to try and get the same 24 hour period from an offset like this:
SELECT *
FROM table_name
WHERE insert_date
BETWEEN DATE_SUB(DATE_SUB(NOW(), INTERVAL 3 HOUR), INTERVAL 1 DAY)
AND DATE_SUB(NOW(), INTERVAL 3 HOUR);
This seems to work fine for my purposes but I want to ask, is there is a more readable and more accurate way, using mysql, to get all rows from the past 24 hours ( between 00:00:00 and 23:59:59 time window ) once a day while running the query from an offset time? I am generally new to all of this so any critiques on my overall approach are more than welcome.
I presume insert_date is a DATETIME?
It seems pointless to go to all the trouble of building two limits and using BETWEEN. I would simply check that DATE(insert_date) is yesterday's date. So
WHERE DATE(insert_date) = CURDATE() - INTERVAL 1 DAY
BETWEEN DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "%Y-%M-%d 00:00:00")
AND DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "%Y-%M-%d 23:59:59")
You could also use Perl date formatting functions to produce the same date-time strings, and interpolate them into the query.
....
WHERE insert_date BETWEEN CURRENT_DATE - INTERVAL 1 DAY
AND
CURRENT_DATE - INTERVAL 1 SECOND;
The lower bound will be coerced to yesterday's YYYY-MM-DD 00:00:00, and this WHERE predicate will be able to make use of an index on insert_date.
Considering that DATE(NOW()) implicitly means midnight this morning, the obvious solution is to take that value and subtract a day for the start... and subtract a second for the end.
BETWEEN DATE_SUB(DATE(NOW()), INTERVAL 1 DAY)
AND DATE_SUB(DATE(NOW()), INTERVAL 1 SECOND)

mySQL - Whole of last month

I am trying to check for all records that occurred last month using the following statement.
Select * from statistics
where statistics_date
BETWEEN date_format(NOW() - INTERVAL 1 MONTH, '%Y-%m-01')
AND last_day(NOW() - INTERVAL 1 MONTH )
However, the selection does not include the last day. What I want is from the first second of the month until the last second of the month.
BETWEEN is notoriously bad for date and timestamp work because it gets the end date wrong.
Here's what you need:
First, let's compute the first day of the present month. You had that exactly right.
DATE_FORMAT(NOW(),'%Y-%m-01')
Next, let's compute the first day of last month:
DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 1 MONTH
Now, we select the records that lie in the interval.
Select *
from statistics
where statistics_date >= DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 1 MONTH
and statistics_date < DATE_FORMAT(NOW(),'%Y-%m-01')
Do you see how the beginning of the date range is chosen with >= and the end with <? Do you see how I used the first day of the present month for the end of the date range? Those things are important, because timestamps can have days and times in them. Consider the timestamp '2013-01-31 23:58'. It happens to be after '2012-01-31' so between won't catch it.
where MONTH(statistics_date) = MONTH(NOW()) - 1

Mysql Datediff query

I need to get the result from the table, which the date should be difference of 5 from the current date.
ie., specific_date column is present in my table. The format of the date is YYYY-MM-DD.
I need the query something like,
SELECT * FROM `table_name` WHERE DATEDIFF(NOW(), specific_date) < 5
It looks like you are trying to do this:
WHERE specific_date < (NOW() + 5 days)
First of all, think carefully about the boundary cases. These boundary cases can bite your ankles in SQL. Do you actually want
WHERE specific_date <= (NOW() + 5 days)
Do your specific_date columns timestamps contain only days (that is dates with times equal to midnight) or do they contain dates and times? If you're going to get the results you want, you need to be careful about those details.
At any rate, try this:
WHERE specific_date <= DATE_ADD(NOW(), INTERVAL 5 DAY)
This is a good way to do such a lookup. The column value stands alone on one side of the inequality predicate (the <=) so mySQL can do an index range scan if you have an index on the column.
Date arithmetic in MySQL is quite flexible. You can do
NOW() + INTERVAL 10 SECOND
NOW() - INTERVAL 2 MINUTE
NOW() + INTERVAL 4 HOUR
CURDATE() - INTERVAL 1 WEEK /* midnight one week ago */
LAST_DAY(NOW()) + INTERVAL 1 DAY - INTERVAL 1 MONTH /*first day of present month*/
NOW() - INTERVAL 1 QUARTER
CURDATE() - INTERVAL 5 YEAR
and so forth.
Have a look at the BETWEEN operator.
expr BETWEEN min AND max
Another way is to use the DATE_SUB operator
WHERE date_column > DATE_SUB(NOW(), INTERVAL 5 DAY)

How to get dates which are between last monday till current day?

I am having dates in my database.
My database is in MySQL.
I want to fetch dates from my database which provides me dates from last monday till current day.
How can I do that?
You first have to work out how many days ago last monday was, using the DAYOFWEEK function, then subtract that from the current date -
SELECT * from table
WHERE date >= DATE_SUB(CURDATE(),INTERVAL MOD(DAYOFWEEK(CURDATE())-2,7) DAY)
AND date <= DATE_ADD(CURDATE(), INTERVAL MOD(7 - (DAYOFWEEK(CURDATE()) - 1), 7) DAY)
I'm not 100% sure about the +/- numbers here, you should be able to work it out from this though
EDIT: If this will only ever be run on the sunday at the end of the period, there is a much simpler version -
SELECT * from table
WHERE date >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
AND date <= CURDATE()
try this one
select * from table
WHERE date >date_sub(curdate(), interval WEEKDAY(curdate()) day) ;
You could always use the between function in your queries...
SELECT *
FROM orders
WHERE order_date between to_date ('2003/01/01', 'yyyy/mm/dd')
AND to_date ('2003/12/31', 'yyyy/mm/dd');
http://www.techonthenet.com/sql/between.php