我有以下查询返回帖子/文章数据和评论(如果有的话)。但是,如果没有对帖子发表评论,则不会返回任何内容,因为(我认为)评论表中没有联接关系。如果没有注释,则不会使用帖子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
答案 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
,所以您可以从左手表中获取所有内容,并从右侧获取相关的行,如果没有,则获取NULL
。 WHERE 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子句条件。