is there a query for me to get the time interval - One minute, five minutes, quarter hour, half hour, hour, and day? I use MySQL as a database.
to get a range, like from 30 to 45 minutes ago, do like this
SELECT * FROM tbl
WHERE tbl.mydate > DATE(DATE_sub(NOW(), INTERVAL 45 MINUTE))
AND tbl.mydate < DATE(DATE_sub(NOW(), INTERVAL 30 MINUTE));
You are probably looking for date_sub:
SELECT * FROM YOURTABLE t
WHERE t.timestamp > date_sub(NOW(), interval 1 hour);
For different intervals you can change the 1 hour to 5 days, 5 weeks, etc).
From the documentation:
DATE_SUB(date,INTERVAL expr unit)
The date argument specifies the starting date or datetime value. expr
is an expression specifying the interval value to be added or
subtracted from the starting date. expr is a string; it may start with
a “-” for negative intervals. unit is a keyword indicating the units
in which the expression should be interpreted.
The following table shows the expected form of the expr argument for
each unit value.
unit Value Expected expr Format
MICROSECOND MICROSECONDS
SECOND SECONDS
MINUTE MINUTES
HOUR HOURS
DAY DAYS
WEEK WEEKS
MONTH MONTHS
QUARTER QUARTERS
YEAR YEARS
Related
For example, if i have search string "2017-12-14" then i need to find all rows that matches 7-day range: "%-12-11", "%-12-12", "%-12-13", "%-12-14", "%-12-15", "%-12-16", "%-12-17".
Is it possible to do with MySql only?
To select same day cross years you can use following trick.
get the list of last 7 days/1 week NOW() - INTERVAL 1 WEEK
get the DAYOFYEAR of that days
search the database for all values of the same day in year
.
SELECT * FROM timevalues
WHERE DAYOFYEAR(timefield) IN (
SELECT DAYOFYEAR(timefield)
FROM timevalues
WHERE DATE(timefield) BETWEEN NOW() - INTERVAL 1 WEEK AND NOW()
)
;
Note: Leap year is not taken into calculation!
According to my brief investigation according to the leap year it would be easier to extend the SQL query with tolerance of 1 day, ie to use - INTERVAL 8 DAY instead of 7 and then control the validity of the day outside the database during processing the data in a loop.
Yes, it is possible.
The function you are looking for is +/- INTERVAL expr unit. See MySQL Date and Time Functions
So to get 7 days back use - INTERVAL 7 DAY:
SELECT *
FROM tablename
WHERE DATE(timefield) BETWEEN '2017-12-14' - INTERVAL 7 DAY AND '2017-12-14'
According to your example would be enough to use -INTERVAL 1 WEEK:
SELECT *
FROM tablename
WHERE DATE(timefield) BETWEEN '2017-12-14' - INTERVAL 1 WEEK AND '2017-12-14'
And List of all possible units
MICROSECOND SECOND MINUTE HOUR DAY WEEK MONTH QUARTER YEAR
SECOND_MICROSECOND MINUTE_MICROSECOND MINUTE_SECOND HOUR_MICROSECOND
HOUR_SECOND HOUR_MINUTE DAY_MICROSECOND DAY_SECOND DAY_MINUTE DAY_HOUR
YEAR_MONTH
This query is selecting rows applied last 30 days:
SELECT `amount` FROM `mg_inputs` WHERE `amount`<0 AND `product`='144' AND DATE(firstedit) BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()
How about queries selecting rows applied last 30 days, but 1 month ago (between: today-30days and today-60days)? Same question goes for "2 months ago". Nothing is working for me at all (SQL is returning errors).
One important thing to note here is that not all months are 30 days, so instead of using INTERVAL DAY use INTERVAL MONTH.
Next, you don't need to use the subtraction sign for dates, you can use the DATE_SUB() function which will do what you need.
Last, keeping those things in mind, you can use the BETWEEN operator to check for rows within a date range. So, for example, if you want all rows from one month ago, try this:
SELECT *
FROM myTable
WHERE dateColumn BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
You should note that for the BETWEEN operator to work properly, the older date must appear first. Here is an SQL Fiddle example that demonstrates that.
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)
I am using this function to filter query results that are older than 60 days:
s.timeSubmitted >= ( CURDATE() - INTERVAL 60 DAY )
The problem is, the "60 days" part doesn't seem to be an exact figure. I want it to filter right where s.timeSubmitted is longer than 60 days, down to the exact second of s.timeSubmitted.
How do I write "60 Days" as an exact figure (down to the second)?
The problem is that CURDATE() returns a DATE type, not a DATETIME type (an instant in time). The result of subtracting an interval from a DATE is also a DATE.
Instead, try this:
s.timeSubmitted >= ( NOW() - INTERVAL 60 DAY )
This gives you what you want, because NOW() returns a DATETIME, so the result of the subtraction is also a DATETIME.
INTERVAL 60 DAY is exact - your problem is that CURDATE() isn't. It returns whole days, not the current time.
Use NOW() instead!
I usually do
now()-interval 60 day
Assuming you want the same time of day 60 days ago;
s.timeSubmitted >= ( now() - interval 60 day);
Maybe an un-necessary note in this case; 1 day ago may be 23, 24 or 25 hours ago depending on DST changes, if you want a specific number of hours as an interval, don't use a day instead of 24 hours.
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)