I have a database with two tables as follow :
Where I want to get the latest Log for each user as :
I can get the result by the query (Q1) :
select u.login, tempLogs.createdDate from User as u,
(select * from Logs as n1 order by n1.createdDate desc ) as tempLogs
where tempLogs.userId = u.id
group by u.login;
But this one (Q2) doesn’t work:
select tempCK.login, tempCK.createdDate from
(select u.login as login, n1.createdDate as createdDate from Logs as n1 , User as u
where n1.userId = u.id
order by n1.createdDate desc
) as tempCK
group by tempCK.login
I expected the result of inner select in Q2 to be ordered and the Q2 group by to take first of each result so the Q2 would be equivalent to Q1 !
Can someone help me to get the difference ?
3
Answers
You can get the latest createdAt from table2 and then can join it with table1 –
I would suggest re-writing your query as per Ankit’s answer as it guarantees to always provide the correct result, however in response to "why" your 2 methods were different:
I believe this happens because the ORDER BY clause in a subquery is ignored by modern optimizers.
https://dev.mysql.com/doc/refman/8.0/en/derived-table-optimization.html says:
In your case, you are using
GROUP BY
in the outer query, so that spoils the first condition above. Therefore the ORDER BY i the derived table is ignored.Your query is a variation of the greatest-n-per-group type of query. Questions about this type of query are asked almost daily on Stack Overflow (but not always tagged as such). There are several types of solutions, such as the answer given by @AnkitBajpai, and others. You can follow that tag to see other answers. For example, in my answer to Retrieving the last record in each group – MySQL