I have an incomplete query that I need some assistance with. It currently runs with a subselect which is inefficient and I am pretty sure using joins would make it a later faster.
Also, there is an element to the query that needs to be added that I’m not quite sure how to do. Details:
I have 3 tables
- album
* albumId
* albumName
- objectTag
* objectTagObjectId (FK reference to albumId)
* objectTabTagId (FK reference to tagId)
- tag
* tagId
* tagName
What I am trying to do is generate a list of random albums (let’s say 50) based on the tags linked to another album passed to the query.
For example, I have an album called “Britney Spears Greatest Hits” and that album is tagged with “pop” and “cheese”. I then pass the query the id of that Britney album and want the query to generate a list of 50 random other albums that are tagged with “pop” and “cheese”.
If there are only 20 albums with those tags then the query should populate the other 30 records with any random album irrespective of tag.
So far I can get the random albums based on tags:
SELECT albumId, albumName, objectTagTagId
FROM album
LEFT JOIN objectTag
ON objectTagObjectId = albumId
WHERE objectTagTagId IN
(
SELECT objectTagTagId
FROM album
LEFT JOIN objectTag
ON objectTagObjectId = albumId
WHERE albumId = 2471
)
ORDER BY RAND()
LIMIT 0,50
As mentioned however, this is inefficient and incomplete:
a) How do I make this more efficient with a join instead of a subselect? Is that possible?
b) How does this query need to be modified so that if there are only x amount of records that match the tags (let’s say 20) that the remainder are filled with random records irrespective of tag?
i cannot vouch for efficiency but here’s an idea…
the count(*) / group by will count the number of tags an album has in common with the src album.
The union will give us 50 filler albums with a cnt of zero, which is ORDERED to the bottom of foo by the ORDER BY and LIMIT.
the ORDER BY RAND() on goo will randomize the order