我有一个SQL数据库,其中存储了与用户关联的用户和标记(多对多关系)。我有经典模式与users
表,tags
表和“桥梁”表usertag
哪个环节有标签的用户:SQL标记列表和标记过滤
users table:
+---------+---------+
| Id | Name |
+---------+---------+
| 1 | Alice |
| 2 | Bob |
| 3 | Carl |
| 4 | David |
| 5 | Eve |
+---------+---------+
tags table:
+---------+---------+
| Id | Name |
+---------+---------+
| 10 | Red |
| 20 | Green |
| 30 | Blue |
+---------+---------+
usertag table:
+---------+---------+
| UserId | TagId |
+---------+---------+
| 2 | 10 |
| 2 | 20 |
| 1 | 30 |
| 4 | 20 |
| 4 | 10 |
| 4 | 30 |
| 5 | 10 |
+---------+---------+
现在,我做了一个查询来检索所有的用户和他们的标签,以逗号分隔场使用GROUP_CONCAT()
功能:
SELECT u.*, GROUP_CONCAT(ut.tagid) as tags FROM users as u LEFT JOIN usertag as ut ON u.id = ut.userid GROUP BY u.id
这给了我正确的输出:
output:
+---------+---------+----------+
| Id | Name | Tags |
+---------+---------+----------+
| 1 | Alice | 30 |
| 2 | Bob | 10,20 |
| 3 | Carl | (null) |
| 4 | David | 10,30,20 |
| 5 | Eve | 10 |
+---------+---------+----------+
的问题是现在我想在其上实现标签过滤,即能够通过标签(或多个标签)查询用户。该过滤器应该使用AND运算符。
例如:获取与标签红用户(10)和绿色(20):
output:
+---------+---------+----------+
| Id | Name | Tags |
+---------+---------+----------+
| 2 | Bob | 10,20 |
| 4 | David | 10,30,20 |
+---------+---------+----------+
又如:获取与标签红用户(10):
output:
+---------+---------+----------+
| Id | Name | Tags |
+---------+---------+----------+
| 2 | Bob | 10,20 |
| 4 | David | 10,30,20 |
| 5 | Eve | 10 |
+---------+---------+----------+
又如:获取与标签红色(10),绿(20)蓝(30)用户:
output:
+---------+---------+----------+
| Id | Name | Tags |
+---------+---------+----------+
| 4 | David | 10,30,20 |
+---------+---------+----------+
我如何能实现这样的查询? This question上等都非常相似,它的实际工作,但它不与GROUP_CONCAT()
领域这是我想保持,因为它是
这里的SQL小提琴处理http://sqlfiddle.com/#!9/291a5c/8
编辑
有人可能会想象,这个查询工作:
获取与标签红(10)和蓝色的所有用户(20):
SELECT u.name, GROUP_CONCAT(ut.tagid)
FROM users as u
JOIN usertag as ut ON u.id = ut.userid
WHERE ut.tagid IN (10,20)
GROUP BY u.id
HAVING COUNT(DISTINCT ut.tagid) = 2
其中给出:
output:
+---------+---------+----------+
| Id | Name | Tags |
+---------+---------+----------+
| 2 | Bob | 10,20 |
| 4 | David | 10,20 |
+---------+---------+----------+
其用户名明智正确的是(Bob和大卫),但Tags
场从大卫的列表中缺少的标签30!
要检查的标签的最大数量是多少? –
@vkp是16,不再有 –