【发布时间】:2013-03-25 01:12:57
【问题描述】:
我有以下与这个问题相关的表格:
project
- projectId (PK)
- projectTitle
- projectDescription
- etc..
tag
- tagId
- tagName
- tagDescription
- etc...
project_tag
- projectId (PK / FK -> project.projectId)
- tagId (PK / FK -> tag.tagId)
我正在实现类似于 StackOverflow 的标签功能,因为它能够查看由一个或多个标签标记的项目列表(在我的例子中是项目)。 我要做的是选择所有项目,这些项目至少带有我提供给查询的所有标签,但同时检索每个单独项目的所有标签。
我现在的工作有效,但我感觉WHERE IN 子句中的子查询效率非常低,因为这可能会针对每一行执行,对吗?
SELECT
`project`.*,
GROUP_CONCAT( DISTINCT `tagName` ORDER BY `tagName` SEPARATOR ' ' ) as `tags`
FROM
`project`
JOIN
`project_tag`
USING ( `projectId` )
JOIN
`tag`
USING ( `tagId` )
WHERE
`projectId` IN (
SELECT
`projectId`
FROM
`project_tag`
JOIN
`tag`
USING ( `tagId` )
WHERE
`tagName` IN ( 'the', 'tags' )
GROUP BY
`projectId`
HAVING
COUNT( DISTINCT `tagName` ) = 2 # the amount of tags in the IN clause
)
GROUP BY
`projectId`
有什么方法可以加入tag 以便我能够同时检索JOINed 项目的所有 标签,而只有JOINing 项目(至少) 匹配我提供给查询的所有标签,而不必使用WHERE IN 子句?
为了说明示例结果,请考虑以下示例项目:
projectId: 1, tags: php, cms, webdevelopment
projectId: 2, tags: php, cms, ajax
projectId: 3, tags: c#, cms, webdevelopment
搜索标签php和cms会得到(这些没有格式化为实际的mysql查询结果,只是为了说明相关数据):
projectId: 1, tags: php, cms, webdevelopment
projectId: 2, tags: php, cms, ajax
不仅仅是:
projectId: 1, tags: php, cms
projectId: 2, tags: php, cms
【问题讨论】: