Reputation: 11157
I have this query with multiple tables and I got the following result. Then I want to group by t.id. I know I can simply use group by t.id but how can I select the latest row of t.id which is url tw5.jpg and created_time 10000004
SELECT p.url,t.name,t.num_photo,t.id
FROM photos AS p
LEFT JOIN tag_maps AS tm ON p.id = tm.photo_id
LEFT JOIN tags AS t ON t.id = tm.tag_id
url created_time name num_photo id
assets/img/tags/tw1.jpg 1000001 my house 1 1
assets/img/tags/tw2.jpg 1000002 dog 1 2
assets/img/tags/tw3.jpg 1000003 taiwan 2 3
assets/img/tags/tw5.jpg 1000004 taiwan 2 3
This is what i get when using group by t.id
url created_time name num_photo id
assets/img/tags/tw1.jpg 1000001 my house 1 1
assets/img/tags/tw2.jpg 1000002 dog 1 2
assets/img/tags/tw3.jpg 1000003 taiwan 2 3
And this is what i want
url created_time name num_photo id
assets/img/tags/tw1.jpg 1000001 my house 1 1
assets/img/tags/tw2.jpg 1000002 dog 1 2
assets/img/tags/tw5.jpg 1000004 taiwan 2 3
EDITED
Photos table
id url created_time
1 assets/img/tags/tw1.jpg 1000001
2 assets/img/tags/tw2.jpg 1000002
3 assets/img/tags/tw3.jpg 1000003
4 assets/img/tags/tw5.jpg 1000004
Tags table
id name num_photo
1 my house 1
2 dog 1
3 taiwan 2
Tag_maps
id tag_id photo_id
1 1 1
2 2 2
3 3 3
4 3 4
Upvotes: 0
Views: 2686
Reputation: 247680
Edit #2: Without seeing sample data from each table or the table structures, I am guessing that the following will work:
SELECT p.url,
created_time,
t.name,
t.num_photo,
t.id
FROM photos p
LEFT JOIN tag_maps AS tm
ON p.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
INNER JOIN
(
select max(created_time) MaxDate, t.id
FROM photos p
LEFT JOIN tag_maps AS tm
ON p.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
group by t.id
) d
on p.created_time = d.MaxDate
and t.id = d.id;
Or another way to write this is with a subquery that returns the max(photo_id)
by tag_Id
from the tag_maps
table and use that result in the join:
SELECT p.url,
created_time,
t.name,
t.num_photo,
t.id
FROM photos p
INNER JOIN
(
select max(photo_id) photo_id, tag_id
from tag_maps
group by tag_id
) AS tm
ON p.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
Result is:
| URL | CREATED_TIME | NAME | NUM_PHOTO | ID |
----------------------------------------------------------------------
| assets/img/tags/tw1.jpg | 1000001 | my house | 1 | 1 |
| assets/img/tags/tw2.jpg | 1000002 | dog | 1 | 2 |
| assets/img/tags/tw5.jpg | 1000004 | taiwan | 2 | 3 |
Edit #1 since your url is different and you want the max(id)
, then you should be able to use:
SELECT p.url,
t.name,
t.num_photo,
Max(t.id) id
FROM photos p
LEFT JOIN tag_maps AS tm
ON p.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
group by t.name, t.num_photo
OP: You can use a subquery:
SELECT p.url,
t.name,
t.num_photo
FROM
(
select MAX(created_time) created_time, url, id
from photos
group by url, id
) AS p
LEFT JOIN tag_maps AS tm
ON p.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
If the id
value in the photos
table is unique for each row, then you might need to use the following:
SELECT p1.url,
t.name,
t.num_photo
FROM photos p1
inner join
(
select MAX(created_time) created_time, url
from photos
group by url
) AS p2
on p1.url = p2.url
and p1.created_time = p2.created_time
LEFT JOIN tag_maps AS tm
ON p1.id = tm.photo_id
LEFT JOIN tags AS t
ON t.id = tm.tag_id
Upvotes: 1