最近我一直致力于高级搜索和他的查询构建器。现在我面临一个小小的
问题,让我说在我的搜索中我想要包含所有完全具有genre_id 100和101的电影,所以基本上我应该只得到movie_id 10
[Movie Table]
movie_id |title |...
10 |Bruce Almighty
11 |Matrix
[Movie Genres Table]
movie_id | genre_id |...
10 |100
11 |101
10 |101
... |...
[movie Version Table]
movie_id | version_id |...
10 |20
10 |21
11 |20
10 |22
[movie language Table]
movie_id | language_id |...
10 |30
10 |40
11 |11
11 |14
,查询如下:
SELECT movie_id,title from movie WHERE title LIKE '%Bruce%'
我不能使用HAVING因为我有更多的字段可以完全相同的版本(标准,扩展等)。
任何想法如何解决这个问题?
更新
我可以继续添加像这样的XD这样的表,基本上是一对多的关系表都具有相同的结构...而且我必须使用dinamically构建查询(这样我只是包含所需的条件)
答案 0 :(得分:0)
进行连接,检查genre_id并对匹配的记录进行计数。
SELECT movie.movie_id, movie.title
from movie
INNER JOIN Genres
ON movie.movie_id = Genres.movie_id
AND Genres.genre_id IN (10, 11)
WHERE title LIKE '%Bruce%'
GROUP BY movie.movie_id, movie.title
HAVING COUNT(*) = 2
如果您需要返回其他字段,那么您可以使用子查询来识别具有HAVING的电影类型
SELECT movie.movie_id, movie.title
from movie
INNER JOIN
(
SELECT movie_id, COUNT(*) AS genre_count
FROM Genres
WHERE genre_id IN (10, 11)
GROUP BY movie_id
HAVING genre_count = 2
) sub1
ON movie.movie_id = sub1.movie_id
WHERE title LIKE '%Bruce%'
编辑 - 检查只有与其相关的流派10和11的电影: -
SELECT movie.movie_id, movie.title
FROM movie
INNER JOIN
(
SELECT movie_id, COUNT(*) AS genre_count
FROM Genres
WHERE genre_id IN (10, 11)
GROUP BY movie_id
HAVING genre_count = 2
) sub1
ON movie.movie_id = sub1.movie_id
LEFT OUTER JOIN
(
SELECT movie_id, COUNT(*) AS genre_count
FROM Genres
WHERE genre_id NOT IN (10, 11)
GROUP BY movie_id
) sub2
ON movie.movie_id = sub2.movie_id
WHERE title LIKE '%Bruce%'
AND sub2.movie_id IS NULL
答案 1 :(得分:0)
只需使用仅包含与两个类型相关联的电影ID的IN子句。
SELECT movie_id, title
FROM movie
WHERE title LIKE '%Bruce%'
AND movie_id IN
(
SELECT movie_id
FROM movie_genre
GROUP BY movie_id
HAVING MIN(genre_id) = 100 AND MAX(genre_id) = 101
);
编辑:这是相同的查询只是更多样化(你可以有更多的价值,他们不需要相邻):
SELECT movie_id, title
FROM movie
WHERE title LIKE '%Bruce%'
AND movie_id IN
(
SELECT movie_id
FROM movie_genre
GROUP BY movie_id
HAVING
MAX(CASE WHEN genre_id = 100 THEN 1 ELSE 0 END) = 1 AND
MAX(CASE WHEN genre_id = 101 THEN 1 ELSE 0 END) = 1
MAX(CASE WHEN genre_id NOT IN (100,101) THEN 1 ELSE 0 END) = 0
);