2

我有以下查询,它返回帖子/文章数据和评论(如果有的话)。但是,如果没有对帖子发表评论,则即使帖子也不会返回任何内容,因为(我认为)评论表中没有连接关系。如果没有评论,则不会使用帖子 ID 创建行。

谁能解释我如何在一个查询中获取帖子数据和所有相关评论?

这是查询: -

        SELECT * FROM posts
                LEFT OUTER JOIN comments
                ON posts.ID = comments.comment_post_id
            WHERE posts.ID = 8 
                AND posts.post_type = 'post' 
                AND posts.post_status = 'publish'
                AND comments.comment_approved = 1
            ORDER BY comments.comment_date_gmt DESC
4

3 回答 3

4

您遇到的问题是,即使表保持连接状态,您也会在 where 子句中通过它进行过滤:

                AND comments.comment_approved = 1

为了完成这项工作,一种选择是:

 SELECT * FROM posts
            LEFT OUTER JOIN comments
            ON posts.ID = comments.comment_post_id
            AND comments.comment_approved = 1
        WHERE posts.ID = 8 
            AND posts.post_type = 'post' 
            AND posts.post_status = 'publish'
        ORDER BY comments.comment_date_gmt DESC

或其他

 SELECT * FROM posts
            LEFT OUTER JOIN comments
            ON posts.ID = comments.comment_post_id
        WHERE posts.ID = 8 
            AND posts.post_type = 'post' 
            AND posts.post_status = 'publish'
            AND (comments.comment_approved IS NULL OR comments.comment_approved = 1)
        ORDER BY comments.comment_date_gmt DESC
于 2013-03-13T13:40:28.403 回答
2

因为你有LEFT OUTER JOIN你会从左边的表和右边的相关行中得到所有,或者NULL如果没有。在WHERE clause你有谓词comments.comment_approved = 1which falsewhencomments.comment_approvedNULL(不相关的)。

移动AND comments.comment_approved = 1到 JOIN 条件。

于 2013-03-13T13:40:14.787 回答
0

重要的是要了解查询处理器如何为外部(左/右/全)连接和 where 子句发挥作用。

对于每个连接,查询处理器都会创建一个包含连接结果的临时结果集(表)。新连接的表中的数据与当前临时结果集包含的任何内容、From 子句中提到的第一个表中的数据或前一个连接的结果集(如果有的话)相结合。

此结果集 id 基于 Joins ON 子句中表达的谓词(条件)过滤,作为此构造过程的一部分进行处理。当然,连接外侧的条件)仅适用于那里有一行的情况。如果不存在匹配行,则无论如何都包含来自内侧的匹配行,并且用空值替换来自外侧的任何列。

然后,这是关键部分,当它完成所有连接并到达 Where 子句时,那里的条件将应用于从所有连接生成的结果集,而不管结果集是如何构造的(内部/外部,十字架等)。因此,如果您对该结果集中的列有条件,该条件来自连接外侧的表,其中包含空值,因为该连接没有来自外部表的匹配行,那么该行将被排除由 Where 子句条件。

于 2013-03-13T14:03:08.080 回答