sql连接问题
Posted
技术标签:
【中文标题】sql连接问题【英文标题】:sql join problem 【发布时间】:2011-02-09 20:26:58 【问题描述】:我想选择所有包含特定标签的帖子。我正在尝试使用此查询:
SELECT GROUP_CONCAT(t.tag_name) taglist
FROM posts p
JOIN posts_tags pt ON p.post_id = pt.post_id
JOIN tags t ON t.tag_id = pt.tag_id
WHERE (p.post_private = 0) AND t.tag_name = 'php'
GROUP BY p.post_id
问题是,上面的查询选择了所有包含php
标签的帖子,但没有选择帖子可能包含的任何其他标签。如果没有AND t.tag_name = 'php'
部分,它会选择帖子的每个标签,但我希望能够按标签过滤...
任何想法如何做到这一点?我尝试了很多东西,但无法弄清楚......
不带AND
语句的样本数据:
|| *taglist* ||
|| php,echo ||
|| c++, cout ||
使用AND
语句的样本数据:
|| *taglist* ||
|| php ||
我想要什么:
|| *taglist* ||
|| php,echo ||
(仅包含 PHP 标签的帖子)
【问题讨论】:
正确加入?你确定这就是你想要的吗? 你说得对,我这里不需要那个,但还是不行 您能否提供示例数据以及您的预期输出是什么? 【参考方案1】:SELECT p.post_id, GROUP_CONCAT(t.tag_name) taglist
FROM posts p
/* These 2 joins get the list of all tags */
INNER JOIN posts_tags pt
ON p.post_id = pt.post_id
INNER JOIN tags t
ON pt.tag_id = t.tag_id
/* These 2 joins guarantee the 'php' tag is included */
INNER JOIN posts_tags pt2
ON p.post_id = pt2.post_id
INNER JOIN tags t2
ON pt2.tag_id = t2.tag_id
AND t2.tag_name = 'php'
WHERE p.post_private = 0
GROUP BY p.post_id
【讨论】:
谢谢,我想我不会找到的。还是不太明白底部的两个连接是如何工作的.. @Sled:底部的两个连接与前两个相同,只是它们还包括条件AND t2.tag_name = 'php'
。因为它们是 INNER 连接,所以它们保证返回的任何帖子都必须具有与之关联的 php 标签。【参考方案2】:
我将尝试解释为什么您的第一次尝试不起作用。
你真正想做的是找到所有一个标签是'php'的帖子。
但是它们的标签分布在许多行中,因此t.tag_name = 'php'
不起作用,因为它会过滤掉所有没有“php”标签的行。
当您要检查依赖于多行的条件时,
您可以创建一个子查询(以查找所有具有 php 标签的 post_id)
p.post_id IN
( SELECT pt2.post_id
FROM post_tags pt2
JOIN tags t2
ON t2.tag_id = pt2.tag_id
WHERE t2.tag_name = 'php'
)
但仍将这些 post_id 与所有相关标签连接起来。
SELECT GROUP_CONCAT(t.tag_name) taglist
FROM posts p
JOIN posts_tags pt
ON p.post_id = pt.post_id
JOIN tags t
ON t.tag_id = pt.tag_id
WHERE (p.post_private = 0)
AND p.post_id IN
( SELECT pt2.post_id
FROM post_tags pt2
JOIN tags t2
ON t2.tag_id = pt2.tag_id
WHERE t2.tag_name = 'php'
)
GROUP BY p.post_id
或者你做的更聪明一点,就像 Stefanelli 展示的另外 2 个 JOIN(其作用类似于子查询)
【讨论】:
以上是关于sql连接问题的主要内容,如果未能解决你的问题,请参考以下文章