选择左连接表的使用和条件

时间:2016-05-12 15:55:05

标签: sql postgresql

这两个查询输出不同的结果,
我有问题AND m.status = $1 ...每个条件都遵循左连接表或移动到最后一部分,那是不同的??

查询1

SELECT count(mua.*) 
  AS total_row_count
  FROM media_user_action mua
    LEFT JOIN media m ON m.id = mua.media_id
      AND m.status = $1
    LEFT JOIN gallery_media gm ON gm.id = mua.media_id
    LEFT JOIN gallery g ON g.id = gm.gallery_id
      AND g.status = $1
    LEFT JOIN "user" mcbu ON mcbu.id = m.create_by_user_id
      AND mcbu.status = $1
    LEFT JOIN "user" gcbu ON gcbu.id = g.create_by_user_id
      AND gcbu.status = $1
WHERE mua.user_id = $2

查询2

SELECT count(mua.*) 
  AS total_row_count
  FROM media_user_action mua
    LEFT JOIN media m ON m.id = mua.media_id
    LEFT JOIN gallery_media gm ON gm.id = mua.media_id
    LEFT JOIN gallery g ON g.id = gm.gallery_id
    LEFT JOIN "user" mcbu ON mcbu.id = m.create_by_user_id
    LEFT JOIN "user" gcbu ON gcbu.id = g.create_by_user_id
WHERE 
m.status = $1
AND g.status = $1
AND mcbu.status = $1
AND gcbu.status = $1
AND mua.user_id = $2

更新
基于以下答案

如果我想确定返回结果,那么所有相关/左连接表状态都必须等于$ 1,(连接表重新编码可能为空)所以我必须添加AND x.status ..跟随连接表,对吧?

3 个答案:

答案 0 :(得分:2)

当您在WHERE - ed的表上放置LEFT JOIN条件,并且要求某些字段具有非NULL值时,您实际上是将LEFT JOIN转换为INNER JOIN

这是因为LEFT JOIN可能会产生联接表没有匹配记录的结果。在那种情况下,那个"虚拟"记录的值为NULL。因此,通过要求其中一个字段不为null,您可以从结果中删除这些实例。

如果恰恰相反,你将这些条件置于LEFT JOIN条件下,那么你不会破坏这种机制,其中不匹配仍会给出结果,尽管有NULL

答案 1 :(得分:2)

外连接意味着除了内连接之外,当找不到匹配时,所有列为null的模拟记录都会被连接。

所以让我们说一个mua我们找不到匹配的m。然后我们得到一个m记录,所有列都为null。 m.status为空。但是,使用WHERE m.status = $1您会忽略该记录,因此您可以使用简单的内部联接。

外连接表的标准属于ON子句。

答案 2 :(得分:2)

使用左外连接时,右表的值可能为NULL

为简单起见,我们说

Table A (id, name)Table B (fid, status)

然后query1就像

select A.id, B.status 
from A
left join (select * from B where status = $1)
on A.id = B.fid;

因此结果可能是B.status NULL

query2就像

select C.* 
from (select A.id, B.status 
      from A
      left join B
      on A.id = B.fid
) C
where C.status = $1;

它等于

select * 
from A
inner join B
on A.id = B.fid
where B.status = $1;

所以B.status必须exactly为1美元,而且永远不会NULL