mysql多对多查询_多个“标签”的Mysql连接查询(多对多关系)匹配所有标签?...

bd96500e110b49cbb3cd949968f18be7.png

I am trying to query for Objects that match ALL of a given set of Tags.

Basically I want users to be able to add on more and more Tags to filter or "narrow down" their search results, kind of like newegg.com does.

My table structure is a table of Objects, a table of Tags, and a MANY:MANY relation table ObjectsTags. So I have a JOIN query like so:

SELECT * FROM Objects

LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)

LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)

I tried using an IN clause/condition, like this:

SELECT * FROM Objects

LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)

LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)

WHERE Tags.name IN ('tag1','tag2')

GROUP BY Objects.id

But I learned that this simulates a series of ORs, so the more tags you add to the query the MORE results you get, instead of the result set narrowing down like I was hoping.

I also tried doing multiple LIKE WHERE conditions, ANDed together:

SELECT * FROM Objects

LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)

LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)

WHERE Tags.name LIKE 'tag1'

AND Tags.name LIKE 'tag2'

GROUP BY Objects.id

But this returns no results, since when the results are grouped together the OUTER JOINed Tags.name column just contains 'tag1', and not also 'tag2'. The result row where 'tag2' matched is "hidden" by the GROUPing.

How can I match ALL of the tags to get the "narrow down" or "drill down" effect that I am after? Thanks.

解决方案

Use:

SELECT *

FROM OBJECTS o

JOIN OBJECTSTAGS ot ON ot.object_id = o.id

JOIN TAGS t ON t.id = ot.tag_id

WHERE t.name IN ('tag1','tag2')

GROUP BY o.id

HAVING COUNT(DISTINCT t.name) = 2

You were missing the HAVING clause.

There's no need to LEFT JOIN if you want only rows where both tags exist.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值