-4

I'm trying to select 6 related videos related to video id X. I've looked through several questions here on SO but none matches my system with genres and such. What I've tried to do was to make an UNION SELECT but that kept listing the same video over and over again, so I gave up.

I have three databases which are off essence right now.

videos - Table containing all videos available. vID vName vCover

genres - A table containing available genres (action, drama, thriller etc.) gID gName

genre_connections - This table contains connections between a genre and a video (thriller -> inception (but with their IDs)) gcID gcVideoID gcGenreID

I want to select 6 videos which are related to the supplied ID. Relations are based on similar genres. So if I'm reviewing a horror/thriller movie the most related video would be a horror/thriller movie and the second most related video would be a horror or thriller movie.

Basically the relations should be based on movies with the same genres ordered by total genres in common, descending.

If it's possible to include would not much hassle a relation between names would also be great. So if I'm reviewing Iron Man the top related videos would be Iron Man 2 and Iron Man 3 and then the genre-related movies would follow.

Magnus
  • 391
  • 1
  • 7
  • 35
  • There is not enough info in your question to give an answer.What does it mean related and how is this logic defined in your db? – Mihai Feb 18 '14 at 22:34
  • As I wrote in the question: _Relations are based on similar genres. So if I'm reviewing a horror/thriller movie the most related video would be a horror/thriller movie and the second most related video would be a horror **or** thriller movie._ :) @Mihai **Edit:** Basically the relations should be based on movies with the same genres ordered by total genres in common, descending. – Magnus Feb 18 '14 at 22:37

3 Answers3

1

The first query is for getting the vID of the film Ironman. You can use vID if you would like to.

SELECT `vID` FROM `videos` WHERE `vName` = 'Ironman';

EDIT:

As Second you need its genreID:

SELECT `gcGenreID`
FROM `genre_connections`
INNER JOIN `videos`
ON `videos`.`vID` = `genre_connections`.`gcVideoID`
WHERE `videos`.`vName` = 'Ironman';

Let's Alias it as temp and join it to a query that asks for videos from this genre.

SELECT `vID`,`vName`,`vCover`
FROM `videos`
INNER JOIN `genre_connections`
ON `videos`.`vID` = `genre_connections`.`gcVideoID`
INNER JOIN (SELECT `gcGenreID` FROM `genre_connections` INNER JOIN `videos` ON `videos`.`vID` = `genre_connections`.`gcVideoID` WHERE `videos`.`vName` = 'Ironman') `temp`
ON `temp`.`gcGenreID` = `genre_connections`.`gcGenreID`;

If you need films related with this name you can use:

SELECT `vID`,`vName`,`vCover`
FROM `videos`
WHERE `vName` LIKE '%Ironman%';

In the end you just need to union them and add a limit:

(SELECT `vID`,`vName`,`vCover`
FROM `videos`
WHERE `vName` LIKE '%Ironman%')
UNION
(SELECT `vID`,`vName`,`vCover`
FROM `videos`
INNER JOIN `genre_connections`
ON `videos`.`vID` = `genre_connections`.`gcVideoID`
INNER JOIN (SELECT `gcGenreID` FROM `genre_connections` INNER JOIN `videos` ON `videos`.`vID` = `genre_connections`.`gcVideoID` WHERE `videos`.`vName` = 'Ironman') `temp`
ON `temp`.`gcGenreID` = `genre_connections`.`gcGenreID`)
LIMIT 6;

I've tested it and run correctly.

androbin
  • 1,622
  • 14
  • 31
  • One the two last queries I get an error (from `mysql_error`) which looks like this: *Not unique table/alias: 'genre_connections'*. Thank you for the answer though! – Magnus Feb 19 '14 at 19:21
  • I've changed the code, please test it, it worked for me. – androbin Feb 21 '14 at 06:35
1

Not tested (no real test data) but the first part of your question could probably be done with a single query like this:-

SELECT d.vID, d.vName, GROUP_CONCAT(e.gName) AS SharedGenre, COUNT(*) AS SharedGenreCount
FROM videos a
INNER JOIN genre_connections b
ON a.vID = b.gcVideoID
INNER JOIN genre_connections c
ON b.gcGenreID = c.gcGenreID
AND b.gcVideoID != c.gcVideoID
INNER JOIN videos d
ON c.gcVideoID = d.vID
INNER JOIN genres e
ON c.gcGenreID = e.gID
WHERE a.vName = 'Iron Man'
GROUP BY d.vID, d.vName
ORDER BY SharedGenreCount DESC
LIMIT 6

For the 2nd part, to match up on similar names, I am not sure how usable it will be. For example, if you search for Dexter do you really want Dexters Laboratory returned? Similarly searching for Aliens on a simple match on name wouldn't find Alien.

I would suggest you possibly need another table to link up a series of films.

Kickstart
  • 21,403
  • 2
  • 21
  • 33
  • I think in a searchbox it's usefull to show Dexters Laboratory. – androbin Feb 20 '14 at 15:27
  • Possibly in a search box (in which case you would probably want to cope with common spelling mistakes, etc), but when just listing 6 most similar items the names are way too likely to be unrelated to be useful like that. Added to which how would a vaguely similar name be compared for relevance to matches on the categories to decide which 6 to show? – Kickstart Feb 20 '14 at 17:09
0

Create an SQL join between videos and generes. Here is how you can do it http://www.w3schools.com/sql/sql_join.asp

and then use like to select the video http://www.w3schools.com/sql/sql_like.asp

Your query would be something like this

SELECT * FROM Videos WHERE Title LIKE '%IronMan';
Muhammad Raihan Muhaimin
  • 5,559
  • 7
  • 47
  • 68