1

我有 3 张桌子:

照片:身份证、姓名

关键字: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) 作为关键字的照片

即)我想检索照片 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;
4

2 回答 2

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 等来执行此操作,但这在很大程度上取决于您对关键字的了解以及如何获取它们。

于 2013-01-30T05:57:18.343 回答
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
于 2013-01-30T07:31:02.693 回答