当没有连接关系时,SQL返回左表

时间:2013-03-13 13:37:35

标签: php mysql sql database phpmyadmin

我有以下查询返回帖子/文章数据和评论(如果有的话)。但是,如果没有对帖子发表评论,则不会返回任何内容,因为(我认为)评论表中没有联接关系。如果没有注释,则不会使用帖子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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

因为您有LEFT OUTER JOIN,所以您可以从左手表中获取所有内容,并从右侧获取相关的行,如果没有,则获取NULLWHERE clause comments.comment_approved = 1 false comments.comment_approved NULL AND comments.comment_approved = 1 {{1}}(未关联)。

将{{1}}移至JOIN条件。

答案 2 :(得分:0)

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

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

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

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