Reputation: 330
I am trying to implement a top-result search for a playlist. The tables are like so:
Playlist: id, title
Assignments: id, youtube_id, position
Videos: youtube_id, title
So joining them is simply: Playlist =(id)= Assignments =(youtube_id)= Videos
I want to find the first playlist on a title match (Titles are not unique) and match it to each of it's videos, to bring back a list of videos in that playlist. I tried the following query:
SELECT *
FROM (
SELECT id, title, position, youtube_id
FROM playlists p
JOIN playlist_assignments pa
USING(id)
WHERE 1 and title = 'My Top Videos'
LIMIT 1
)d
JOIN videos v
USING (youtube_id)
ORDER BY position ASC
Unfortunately, the query will only return 1 row, the playlist matched with just the first video. How can I limit the subquery to just the top result, but still have a final result of a multiple row answer?
Upvotes: 0
Views: 1962
Reputation: 6645
The issue with your query is that the sub-query is doing a LIMIT 1
, which means that though you retrieved a single playlist but then you also retrieved a single youtube_id
. Then when did you ran a JOIN with videos
on that single youtube_id
, it gives you a single record.
The fix might be to SELECT only from playlists
table in the sub-query and move the JOIN for playlist_assignments
outside together with the videos
join. Something like:
SELECT *
FROM (
SELECT id, title, position, youtube_id
FROM playlists p
WHERE title = 'My Top Videos'
LIMIT 1
) d
JOIN playlist_assignments pa USING (id)
JOIN videos v
USING (youtube_id)
ORDER BY position ASC;
My suggested query is:
SELECT `p`.`id` `playlist_id`, `p`.`title` `playlist_title`, `v`.`youtube_id` `youtube_id`, `v`.`title` `youtube_title`, `pa`.`position`
FROM `playlists` `p`
INNER JOIN `playlist_assignments` `pa` ON `p`.`id` = `pa`.`id`
INNER JOIN `videos` `v` ON `pa`.`youtube_id` = `v`.`youtube_id`
WHERE `p`.`title` = 'My Top Videos'
ORDER BY `pa`.`position`;
Hope this helps. Let me know if it worked or if it didn't.
Upvotes: 2
Reputation: 3348
The way your query is written, you limit the results from playlist_assignments to 1. If I understand correctly, you just want one playlist but all the videos from that playlist. In that case, modifying your query this way should work
SELECT *
FROM (
SELECT id, title
FROM playlists p
WHERE 1 and title = 'My Top Videos'
LIMIT 1
)d
JOIN playlist_assignments pa
USING(id)
JOIN videos v
USING (youtube_id)
ORDER BY position ASC
Upvotes: 0
Reputation: 1494
I have not tested, but the idea is to try to use an aggregate MIN in your subquery to get min playlist id for each youtube videos you have, and then join it to the playlist table
SELECT p.*, v.*
FROM
(SELECT MIN(id) AS id, youtube_id
FROM playlists p
JOIN playlist_assignments pa USING(id)
WHERE Title = 'My Top Videos'
GROUP BY youtube_id) AS firstPlaylistByVideo
JOIN playlists p ON p.id = firstPlaylistByVideo.id
JOIN videos v USING (youtube_id)
ORDER BY position ASC
Upvotes: 0