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连接问题的主要内容,如果未能解决你的问题,请参考以下文章

java sql数据连接池的问题?

sql 数据库连接超时

SQL SERVER2000不允许远程连接问题

SQL2000 突然不能远程连接空间里面的数据库了

SQL 连接差异

一个sql连接表的问题