2011-04-25 47 views
1

我有两个表。SQL查询来查找包含资源不止一个标签

Resource: 
md5 (PK), link, title 

Tags: 
md5 (FK), category 

这是一个一对多的关系,使得资源可以有多个标签。 我希望能够提取具有两个标签的资源,例如一个包含标签'web'和'blog'的资源。如果我使用“OR”,这显然会返回甚至只包含“网络”或只包含“博客”的文件,但如果我使用AND,我没有得到任何结果,即使我知道有包含这两个标签资源

SELECT DISTINCT tags.MD5, Resource.Title, Resource.Link, tags.Category 
FROM Resource 
INNER JOIN tags ON Resource.MD5 = tags.MD5 
WHERE  
    (tags.Category = @tag) 
OR 
    (tags.Category = @tag2) 
ORDER BY tags.MD5 

回答

4

你想要做这样的:

select t.MD5, r.Title, r.Link, t.Category 
from Resource r inner join Tags t on r.MD5 = t.MD5 
where exists (select category from Tags t1 where category = @tag and t1.MD5 = r.MD5) 
and exists (select category from Tags t1 where category = @tag2 and t1.MD5 = r.MD5) 
+1

+1如果您希望所有**标签仅用于那些至少包含@tag AND @ tag2的资源,那么这是一个较好的解决方案。 – 2011-04-25 19:23:32

+0

基于OP所需的输出,这是什么意 – 2011-04-25 19:26:47

+3

的EXISTS是让您轻松处理其他逻辑,像“资源与标签A或B”的美:'选择X与Y WHERE EXISTS(...)或者虽然存在(...)'。根据我的经验,这非常有用,速度非常快,通常比用于反连接的“LEFT JOIN”或“NOT IN()”更快。 – 2011-04-25 19:28:22

3

下面将筛选出的资源不具备这两个标签:

SELECT DISTINCT Resource.MD5, Resource.Title, Resource.Link, t1.Category, t2.Category 
FROM Resource 
INNER JOIN tags t1 ON Resource.MD5 = t1.MD5 AND t1.category = @tag 
INNER JOIN tags t2 ON Resource.MD5 = t2.MD5 AND t2.category = @tag2 
+0

比ks很好的解决方案 – michelle 2011-04-25 19:29:53

+0

我不认为SQL是100%有效的,但它是正确的想法,所以+1无论如何。 – Neil 2011-04-25 20:09:30

+0

哦,如果您希望所有为这些资源返回的标签都使用匹配的标签,您可以第三次加入标签。 – Neil 2011-04-25 20:11:00

2
select r.* 
from resource as r 
left join tags as t 
on r.md5 = t.md5 
where t.category in ('web','blog') 
group by r.md5 
having count(distinct(t.category)) = 2 
+0

感谢您的回复。这也行得通,但是我将不得不和阿德里安一起去,因为存在提供了更好的表现。 – michelle 2011-04-25 19:34:40

+0

没问题。我更喜欢他的解决方案。 :) – 2011-04-25 19:35:42