什么MySQL查询可以返回满足所有条件的结果集,例如返回所有具有这些“x”关键字的照片?

时间:2013-01-30 04:05:12

标签: mysql join

我有3张桌子:

照片:id,名称

关键字:id,关键字

photo_keyword关系表:photo_id,keyword_id

换句话说,一张照片可能与描述照片的多个关键字相关联

photos:
id | name
1  | photo 1
2  | photo 2
3  | photo 3

keywords:
id | keyword
1  | NHL
2  | Toronto
3  | Montreal
4  | Boston
5  | Chicago
6  | Canadiens
7  | Leafs


photo_keyword:
photo_id | keyword_id
1 | 2
1 | 7
1 | 1
2 | 1
2 | 3
2 | 6
3 | 2
3 | 7

我想动态地编写/构建查询,我可以获得符合所有要求标准的照片列表。

示例:我希望所有将Toronto(2)和Leafs(7)作为关键字的照片

ie)我想检索照片1和照片3,因为它们是具有两个关键字的两个

如果我要求将NHL(1)Toronto(2)和Leafs(7)作为标准的照片,则只返回照片1。

显而易见的第一次尝试涉及加入表格:

SELECT photo.id, photo.name
FROM photo
LEFT JOIN photo_keyword ON photo_keyword.photo_id = photo.id
LEFT JOIN keyword ON keyword.id = photo_keyword.keyword_id
WHERE keyword.keyword = 'Toronto'

返回照片1和2

每当我搜索符合1个关键字条件的所有照片时,都可以使用此类查询。然而, 试图获得符合两个关键字标准的照片是另一回事。

我试过

 WHERE keyword.keyword IN ('NHL, 'Toronto', 'Leafs') 

但是返回符合任一标准但不一定兼顾的照片。在这种情况下,照片1和2也是如此。

那么如何构建仅返回符合所有关键字条件的照片的查询?

对此的任何帮助都将非常感激!

更新

每个人的评论都是我放在一起,似乎按照我的要求做的:

SELECT
    photos.id
FROM photos
LEFT JOIN photo_keyword pk ON pk.photo_id = photos.id
LEFT JOIN keywords kw ON kw.id = pk.keyword_id
WHERE kw.keyword IN ('NHL', 'Toronto', 'Leafs')
GROUP BY photos.id
HAVING COUNT(kw.keyword) = 3;

2 个答案:

答案 0 :(得分:1)

如果您知道某张照片无法重复关键字,我认为您可以通过以下方式完成此操作:

SELECT photo.name from photo where photo.id IN (
SELECT photo.id
FROM photo
LEFT JOIN photo_keyword ON photo_keyword.photo_id = photo.id
LEFT JOIN keyword ON keyword.id = photo_keyword.keyword_id
WHERE keyword.keyword IN ('NHL, 'Toronto', 'Leafs')
GROUP BY (photo.id)
HAVING COUNT (photo.name) = *Number of passed keywords*)

也可以使用UNIONS等执行此操作,但这很大程度上取决于您对关键字的了解以及获取关键字的方式。

答案 1 :(得分:1)

尝试此查询 -

SELECT p.id, p.name FROM photo_keyword pk
  JOIN keywords k
    ON k.id = pk.keyword_id
   JOIN photos p
     ON p.id = pk.photo_id
GROUP BY
  pk.photo_id
HAVING 
  COUNT(IF(k.keyword = 'Toronto', 1, NULL)) > 0 AND
  COUNT(IF(k.keyword = 'Leafs', 1, NULL)) > 0