从另一个表中选择一个集合中包含的行

时间:2016-03-07 23:08:33

标签: mysql sql join exists

我有一张桌子"产品"产品名称和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)部分,则查询有效。如上所述,它没有显示错误,但也没有结果;我应该怎么写这样我才能得到一组有一个标签的产品,并且标签把手有/或其他指定的标签?

2 个答案:

答案 0 :(得分:2)

我喜欢使用group byhaving来解决此类问题 - 因为我发现此方法可以很好地表达许多不同的条件。根据您的条件:

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')
)
;