I am attempting to find the latest log entries in my MySQL database. I cooked up this query late last night but upon testing today it does not seem to be returning the correct data.
SELECT MAX(id), hostName, email, info, time
FROM log
WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY hostName
ORDER BY `time` DESC
The query runs just fine, but none of the other fields seem to match the id column. It grabs the max id number, but the hostName, email, and info do not match the id, and they are not the latest. I've spent a few hours spinning my wheels on this (I'm a MySQL noob and just doing this for fun) so I'm pretty confused now..
Thanks for any help!
EDIT: Wow thanks for all the responses! Sorry for the confusion, I should have said "I want the latest log per hostname!" <- That is specifically what I need.
You said:
I am attempting to find the latest log entries in my MySQL database
There is no need to group nor use a subquery. Just try this:
SELECT id, hostName, email, info, time FROM log
WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY `time` DESC
Now you said:
I want the latest log per hostname!
Then the solution should be this:
SELECT l1.id, l1.hostName, l1.email, l1.info, l1.time FROM log l1
LEFT JOIN log l2 on l1.hostName = l2.hostName AND l1.time < l2.time
WHERE l2.time IS NULL
ORDER BY l1.time DESC
If you want the full row that corresponds to the max id for each distinct hostName
,
SELECT id, hostName, email, info, time
FROM log
WHERE id IN
(SELECT MAX(id) FROM log WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY hostName)
ORDER BY `time` DESC
Another way to do the same thing is to GROUP BY
and then JOIN
to the log table:
If "latest" means the maximum id
, use a (hostname, time, id)
index and this:
SELECT log.id
FROM
log
JOIN
( SELECT MAX(id) AS id
FROM log
WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY hostName
) AS grp
ON grp.id = log.id ;
UPDATE : You may alo want to try this one. It just might be more efficient (depending on the hostname distribution) - and would benefit from a index: (hostname, id, time)
index:
SELECT log.id
FROM
log
JOIN
( SELECT MAX(id) AS id
FROM log
GROUP BY hostName
) AS grp
ON grp.id = log.id
WHERE log.time >= DATE_SUB(NOW(), INTERVAL 1 HOUR) ;
If "latest" means the maximum time
(eg if time
is insertion_time
and is not changed later), use a (hostname, time)
index and this:
SELECT log.*
FROM
log
JOIN
( SELECT hostname, MAX(time) AS max_time
FROM log
WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY hostname
) AS grp
ON grp.hostname = log.hostname
AND grp.max_time = log.time ;
And finally, since everyone forgot to answer the "Why mysql query is returning wrong Results?" question, here is another question with some useful answers: Why does MySQL add a feature that conflicts with SQL standards?
This is a famous one:
SELECT *
FROM log
WHERE log.id IN (
SELECT MAX(id)
FROM log
WHERE time >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY hostName) T
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.