我有一张桌子"产品"产品名称和ID:
id | title
1 product 1
2 product 2
每个产品都可以有一系列标签。标签在表格#34;属性":
中标识id | name | handle
1 Tag One tag-one
2 Tag Two tag-two
3 Tag Three tag-three
4 Tag Four tag-four
etc
产品与标签的关系是另一个表格"标签":
id | AttId | OwnerId
1 1 1
2 2 1
3 1 2
4 3 2
etc
好的,所以我试图选择一组产品,这些产品都至少有一个特定的标签,并可能选择其他标签。以下是我现在正在使用的内容:
SELECT products.id
FROM products
WHERE
EXISTS
(
SELECT 1
FROM Tags
INNER JOIN Attributes ON tags.AttId = Attributes.id
WHERE Attributes.handle = 'tag-one'
AND (
Attributes.handle = 'tag-two'
OR
Attributes.handle = 'tag-four'
)
AND products.id = Tags.OwnerId
)
如果我删除了AND(OR)部分,则查询有效。如上所述,它没有显示错误,但也没有结果;我应该怎么写这样我才能得到一组有一个标签的产品,并且标签把手有/或其他指定的标签?
答案 0 :(得分:2)
我喜欢使用group by
和having
来解决此类问题 - 因为我发现此方法可以很好地表达许多不同的条件。根据您的条件:
select p.*
from products p join
tags t
on t.OwnerId = p.id join
attributes a
on t.attid = a.id
group by p.id
having sum(a.handle = 'tag-one') > 0 and
sum(a.handle in ('tag-two', 'tag-four')) > 0;
having
子句中的每个条件都会计算与条件匹配的行数(对于产品)。第一个说至少有一行'tag-one'
句柄。第二个说,至少有一行与另外两个句柄。
答案 1 :(得分:0)
我认为如果您执行两个单独的查询并选择交叉点,那么它将为您提供所需的内容。
-- Get all the owner ids that have 'tag-one'
select OwnerId
from Tags t1
where AttId in
(
select id
from Attributes a1
where a1.handle = 'tag-one'
)
intersect
-- Get all the owner ids that have tag-two and tag-four
select OwnerId
from Tags t2
where AttId in
(
select id
from Attributes a2
where a2.handle in ('tag-two', 'tag-four')
)
;