Display rows from MySQL where a datetime is within the next hour - mysql

I always have trouble with complicated SQL queries.
This is what I have
$query = '
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND active = 1
ORDER BY date_time ASC
LIMIT 6
';
I want to get up to 6 rows that are upcoming within the hour. Is my query wrong? It does not seem to get events that are upcoming within the next hour when I test it.
What is the correct syntax for this?

I'm going to postulate that you're looking at a group of records that contain a range of DATETIME values, so you probably want something more like this:
SELECT id,
name,
info,
date_time
FROM acms_events
WHERE date_time < DATE_ADD(NOW(), INTERVAL 1 HOUR)
AND date_time >= NOW()
AND active = 1
ORDER BY date_time ASC
LIMIT 6
Otherwise, your query is looking for records with a date_time of exactly "now + 1 hour". I'm assuming all your dates aren't specific to that particular second. ;)
To clarify a bit, DATE_ADD() and DATE_SUB() return exact timestamps, so your query above roughly translates to something like SELECT ... WHERE date_time = '2010-04-14 23:10:05' ORDER BY ..., which I don't think is what you want.

WHERE date_time = DATE_SUB(NOW(), INTERVAL 1 HOUR)
means date_time equals exactly now minus one hour, which would result in any record exactly one hour old.
Why not use
WHERE TIMEDIFF(date_time, NOW()) < '01:00:00'
AND date_time > NOW()

Related

How to get rows from MySQL table with two field to order by?

I have a table in MySQL with fields:
id - int;
date - datetime;
rating - decimal(3,2);
and so on, other fields are not necessary in this selection.
There are about 6000 rows in the table.
I have to get rows from the table that is ordered by rating ASC for the last 6 months and then other rows ordered by id ASC.
How can I do it?Will it work fast?
I would do something like this to achieve that:
select *
from tbl
order by case
when date >= DATE_ADD(curdate(), INTERVAL -6 MONTH) then
rating
else id
end ASC;
You need to make sure that all the records from the last 6 months come first in the result, and then worry about ordering by rating or id. You can do that by ordering on the boolean
date >= CURDATE() - INTERVAL 6 MONTH
first, and then on either rating or id as appropriate. For example:
SELECT *
FROM data
ORDER BY date >= CURDATE() - INTERVAL 6 MONTH DESC,
CASE WHEN date >= CURDATE() - INTERVAL 6 MONTH THEN rating
ELSE id
END

How can I add days to a date in MYSQL in a query

I am trying to add 5 days to a date in MYSQL in a query. This is what I have done:
SELECT * FROM sales INNER JOIN partner on user_id = idpartner WHERE DATE((end_date) + 5) >= DATE(NOW()) ORDER BY end_date ASC LIMIT 0,50000
But this is not showing the list of sales which has ended. Can someone please tell me where I am making a mistake.
It looks like you want rows where end_date is later than five days ago.
The best way to get that is with
WHERE end_date >= CURDATE() - INTERVAL 5 DAY
The business of adding integers to dates doesn't work in MySQL (it's an Oracle thing). So you need to use the INTERVAL n unit syntax.
You'll notice that my WHERE clause above is functionally equivalent to
WHERE DATE(end_date) + INTERVAL 5 DAY >= DATE(NOW())
But, the first formulation is superior to the second for two reasons.
if you mention end_date in a WHERE clause without wrapping it in computations, your query can exploit an index on that column and can run faster.
DATE(NOW()) and CURDATE() both refer to the first moment of today (midnight). But CURDATE() is a bit simpler.
To fix the original query, you can use DATE_ADD with the INTERVAL keyword:
SELECT
*
FROM
sales
INNER JOIN
partner ON user_id = idpartner
WHERE
DATE_ADD(end_date, INTERVAL 5 DAY) >= DATE(NOW())
ORDER BY end_date ASC
LIMIT 0 , 50000
Said that, I wouldn't recommend applying functions such as DATE_ADD on columns, as it means that the database won't be able to use an index on end_date. Therefore, I would modify the query to:
SELECT
*
FROM
sales
INNER JOIN
partner ON user_id = idpartner
WHERE
end_date <= DATE_ADD(DATE(NOW()), INTERVAL 5 DAY)
ORDER BY end_date ASC
LIMIT 0 , 50000
As you can see, in the second alternative all functions are applied on constants and not on columns (end_date).
You can try
DATE_ADD() here is the
Link
Select DATE_ADD(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 1 DAY) FROM DUAL

SQL Query by created 3 hours ago

Given a set of data with date_created stored like 2017-04-13 23:29:52, how would I construct an SQL query to select all items that were created within the last 3 hours?
I originally thought to do something like this:
SELECT
*,
MAX(date_created)
FROM items
GROUP BY date_created
but that would not be exactly what I want. I'm not sure how to go about this.
Use NOW() and INTERVAL in your WHERE clause
SELECT * FROM items WHERE date_created <= NOW() - INTERVAL 180 minute AND date_created >= NOW() - INTERVAL 210 minute
This one uses CURDATE, CURDATE and DATE_ADD:
SELECT *
FROM items
WHERE DATE(date_created) = CURDATE()
AND TIME(date_created) BETWEEN CURTIME() AND DATE_ADD(CURTIME(), INTERVAL -3 HOUR)
select * from items where
extract(hours from age(current_timestamp, date_created))>=3;
Extract keyword would extract hours difference from current timestamp and return only that is greater than or equal to 3.

MySQL Date Transformation in Group By

I have the following query:
SELECT COUNT(*) AS COUNT, DATE(POST_DATE) AS POST_DATE
FROM POST
WHERE POST_DATE>='?'
GROUP BY DATE(POST_DATE)
POST_DATE is actually a DATETIME.
Now, this query works fine except I'd like to make one small adjustment. I would like all posts before 6am count as a post from yesterday.
So somehow I need to say: if POST_DATE.hour < 6 -> date(POST_DATE) - 1
But I'm not sure how to this in this query... or if that's even possible.
My first thought is to do another query with the date transformation and then wrap that result with the count and groupby
Any thoughts from an SQL wizard?
You want all posts from before 6am on day n+1 to be tabulated as if they were from day n. That means you want them to be tabulated as if they were made six hours earlier than the actual time stamp.
Here's what you do.
SELECT COUNT(*) AS COUNT,
DATE(POST_DATE - INTERVAL 6 HOUR) AS POST_DATE
FROM POST
WHERE DATE(POST_DATE - INTERVAL 6 HOUR) = ?
GROUP BY DATE(POST_DATE - INTERVAL 6 HOUR)
In all cases, you just offset the POST_DATE by six hours. I assume that when you choose a particular day for posts you want it to run from 06:00 to 06:00, not midnight to midnight.
Notice that your WHERE clause defeats the use of an index on POST_DATE, because of the function on the column value. You may want this instead.
WHERE POST_DATE >= ? + INTERVAL 6 HOUR
AND POST_DATE < ? + INTERVAL 1 DAY + INTERVAL 6 HOUR
SELECT COUNT(*) AS COUNT, case when hour(POST_DATE) >= 6
then DATE(POST_DATE)
else POST_DATE - interval 1 day
end AS NEW_POST_DATE
FROM POST
WHERE POST_DATE >= '?'
GROUP BY NEW_POST_DATE

MYSQL select where date within this day

MY query looks like this:
SELECT COUNT(entryID)
FROM table
WHERE date >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
Will this count the rows whose date values are within the day (starting at 12:00; not within 24 hours)? If not, how do I do so?
The following should be enough to get records within the current day:
SELECT COUNT(entryID)
FROM table
WHERE date >= CURDATE()
As Michael notes in the comments, it looks at all records within the last two days in its current form.
The >= operator is only necessary if date is actually a datetime - if it's just a date type, = should suffice.
Here's the solution:
SELECT COUNT(entryID)
FROM table
WHERE DATE(date) >= CURDATE()
Since my date column is type DATETIME, I use DATE(date) to just get the date part, not the time part.
CURDATE() returns a date like '2012-03-30', not a timestamp like '2012-03-30 21:38:17'. The subtraction of one day also returns just a date, not a timestamp. If you want to think of a date as a timestamp think of it as the beginning of that day, meaning a time of '00:00:00'.
And this is the reason, why this
WHERE date >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
and this
WHERE date > CURDATE()
do the same.
I have another hint: SELECT COUNT(entryID) and SELECT COUNT(*) give the same result. SELECT COUNT(*) gives the database-machine more posibilities to optimize counting, so COUNT(*) is often (not always) faster than COUNT(field).