他们做同样的事情,但我想知道是否存在一些差异,我的意思是表现......
TB1 : tb1_id - > PK ...
TB2 : tb1_id - > FK ...
select columns ... from tb1 a left join tb2 b
on a.tb1_id=b.tb1_id and b.uid=xxxxxxx where a.tb1_id=yyy limit 1
select columns ... from tb1 a left join tb2 b
on a.tb1_id=b.tb1_id where a.tb1_id=yyy and b.uid=xxxxxxx limit 1
感谢。
答案 0 :(得分:2)
稍微简化一下你可以认为首先评估你的JOIN
,然后应用WHERE
s过滤器。使用这个公式:
1)您的第一个查询将返回表a
中的所有记录以及表b
中的相应记录(如果存在,否则为一组NULL
s)具有匹配的{{ 1}}和tb1_id
字段中的某个值。然后,结果集将被过滤为仅包含uid
的记录,并将第一条记录返回给客户端。
2)您的第二个查询将返回表a.tb1_id=yyy
中的所有记录以及表a
中的相应记录(如果存在,否则为一组b
s)具有匹配的{{ 1}}。结果集将被过滤掉,只包含NULL
中具有特定值的记录以及tb1_id
中的特定值。最后一部分很重要。此特定条件将丢弃表a.tb1_id
中仅{1}}中没有匹配集的所有记录,仅仅因为b.uid
。基本上,你不会在a
中混合b
和“硬”条件。执行此操作后,您会立即将NULL != xxxxxxx
加入转换为LEFT JOIN
加入。剩余集合的第一条记录将返回给客户。
那就是说,在你的情况下你可能会得到相同的结果。无独有偶。您的查询中没有WHERE
,因此返回的记录顺序取决于数据库引擎(您最好不要认为它不具有确定性且无法依赖,它很可能是如此并且恰好可能发生这样的情况:两个查询返回的第一个记录是匹配所有条件的记录 - OUTER
和INNER
中的ORDER BY
匹配以及{{1}在tb1_id
中。
答案 1 :(得分:1)
在没有注意到JOIN的'LEFT'部分之后,我怀疑我原来的答案。经过一些快速研究后,我修改了我的答案。
这个article详细解释了一些事情,表明查询的实际处理方式不同。
以下文中的示例显示了这一点。
mysql> SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id | weight | exist |
+----+--------+------+--------+-------+
| 1 | 100 | NULL | NULL | NULL |
| 2 | 200 | 2 | 22 | 0 |
| 3 | 300 | NULL | NULL | NULL |
| 4 | 400 | NULL | NULL | NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM product LEFT JOIN product_details
ON (product.id = product_details.id)
WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
| 2 | 200 | 2 | 22 | 0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)
答案 2 :(得分:1)
他们不一样。请参阅@Pavel_Veller提供的答案这只是为了支持他的回答。在Postgres上运行:
create table tb1( tb1_id int );
create table tb2( tb1_id int, uid int );
insert into tb1 values( 1 );
insert into tb2 values( 1, 0 );
select a.tb1_id
from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
where a.tb1_id = 1;
select a.tb1_id
from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
where a.tb1_id = 1
and b.uid = 3;
结果:
postgres=# select a.tb1_id
postgres-# from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
postgres-# where a.tb1_id = 1;
tb1_id
--------
1
(1 row)
postgres=# select a.tb1_id
postgres-# from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
postgres-# where a.tb1_id = 1
postgres-# and b.uid = 3;
tb1_id
--------
(0 rows)
答案 3 :(得分:0)
这两个查询完全没有相同的做法,第一个查询可能不会从b返回任何行,而第二个查询不会从a返回任何行,如果没有b的有效连接则返回b。
Mysql解释where子句中的“=”,好像它是一个INNER连接(它不是连接,但在这种情况下使用的方式相同)