Reputation: 1006
This is i think a simple problem but i can't seem to solve it.
I want to select the newest result from a table and join it with a single element in another table.
To put it better, here's a simple schema:
Table 1 - Person
personId -PK - INT - AUTO ID
name - VARCHAR
Table 2 - Event
eventId - PK - INT - AUTO ID
personId - FK
timestamp - DATETIME
event - ENUM ('Went Out', 'Came back')
What I'd like to do is return a list of all people and the latest action each person performed
Example Result:
name| personId | timestamp | eventId | event
bob | 1 | 2011-08-7 3 | 'went out'
I did a simple query joining the two tables and then did a group by personId and order by timestamp but the result that was returned was always the first action for the person, not their latest.
Any Ideas?
Upvotes: 1
Views: 257
Reputation: 62504
SELECT p.name, p.personId, e.timestamp, e.eventId, e.event
FROM person p
INNER JOIN Event e
ON e.eventId =
( SELECT MAX(eventId)
FROM Event
WHERE personId = p.personId
GROUP BY personId
LIMIT 1 )
OR
SELECT p.Name, p.ID, me.timestamp, me.ID, me.event
FROM person p
INNER JOIN (
SELECT id, timestamp, event
FROM Event
WHERE personId = p.ID
ORDER BY timestamp DESC LIMIT 1
) me
ON p.ID = me.id
PS: sorry but can't test both queries right now
Upvotes: 3
Reputation: 2694
An alternative solution, making use of a covered key, assumes that order by Id
would yield the same results as order by timestamp
SELECT p.Name, p.ID, me.timestamp, me.ID, me.event
FROM person p
JOIN (
SELECT personId, MAX(ID) id
FROM Event
WHERE personId = p.ID
GROUP BY personId
) me
ON p.ID = me.id
Order by timestamp
is more natural and probably safer, but this is quicker.
Upvotes: 0
Reputation: 27474
The ANSI standard way would be:
select name, personid, timestamp, eventid, event
from person
join event on event.personid=person.personid
and event.timestamp=(select max(timestamp) from event e2
where e2.personid=person.personid)
I haven't used MySQL in a while and I don't have an installation handy, but you might get what you want with:
select name, personid, timestamp, eventid, event
from person
join event on event.personid=person.personid
group by personid
order by personid, timestamp desc
It's non-standard because by the standard, anything in the select must be in the group-by or be an aggregate, and here we don't want to do either. But as I recall MySQL doesn't require that, so I'd give this a whirl and see what happens.
Upvotes: 0
Reputation: 86882
SELECT
t1.Name,
t1.PersonId,
t2.TimeStamp,
t2.EventId,
t2.Event
FROM Table1 t1
INNER JOIN Table2 t2 ON t2.PersonId = t1.PersonID
INNER JOIN (SELECT
PersonId,
MAX(TimeStamp) as LastEventDateTime
FROM Table2
GROUP BY PersonID) LE
ON LE.PersonID = t2.PersonID
AND LE.LastEventDateTime = t2.TimeStamp
Upvotes: 3
Reputation: 64399
you'd want to do an
ORDER by `timestamp` DESC
(desc from descending) to get the highest timestamp value instead of the lowest
Upvotes: 0