关于在SQL语句中ON和WHERE中条件使用的差异

Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE测试条件如下

create table customers
(
customerid char(5),
city varchar(10)
);
go
create table orders
(
orderid int,
customerid char(5)
);
go
insert into customers values('FISSA','Madrid');
insert into customers values('FRNDO','Madrid');
insert into customers values('KRLOS','Madrid');
insert into customers values('MRPHS','Zion');

insert into orders values(1,'FRNDO');
insert into orders values(2,'FRNDO');
insert into orders values(3,'KRLOS');
insert into orders values(4,'KRLOS');
insert into orders values(5,'KRLOS');
insert into orders values(6,'MRPHS');
insert into orders values(7,NULL);

select c.customerid,o.customerid,c.city,o.orderid as numorders
from customers as c
left outer join orders as o
on c.customerid=o.customerid  and c.city='Madrid'

select c.customerid,o.customerid,c.city,o.orderid as numorders
from customers as c
left outer join orders as o
on c.customerid=o.customerid  
where c.city='Madrid'

 

查询情况

select * from customers
FISSA    Madrid
FRNDO    Madrid
KRLOS    Madrid
MRPHS    Zion

select * from orders
1    FRNDO
2    FRNDO
3    KRLOS
4    KRLOS
5    KRLOS
6    MRPHS
7    NULL

select c.customerid,o.customerid,c.city,o.orderid as numorders
from customers as c
left outer join orders as o
on c.customerid=o.customerid  and c.city='Madrid'
FISSA    NULL    Madrid    NULL
FRNDO    FRNDO    Madrid    1
FRNDO    FRNDO    Madrid    2
KRLOS    KRLOS    Madrid    3
KRLOS    KRLOS    Madrid    4
KRLOS    KRLOS    Madrid    5
MRPHS    NULL    Zion    NULL

select c.customerid,o.customerid,c.city,o.orderid as numorders
from customers as c
left outer join orders as o
on c.customerid=o.customerid  
where c.city='Madrid'
FISSA    NULL    Madrid    NULL
FRNDO    FRNDO    Madrid    1
FRNDO    FRNDO    Madrid    2
KRLOS    KRLOS    Madrid    3
KRLOS    KRLOS    Madrid    4
KRLOS    KRLOS    Madrid    5

SQLServer2005中的查询中,SQLServer对查询语句的解析顺序如下:

1.         SQLServer先按照From表进行笛卡尔乘积

即对customerorder做笛卡尔乘积,得到一个28行的虚拟表,以上两条SQL语句是完全一致的。

2.         然后按照ON的顺序校验True/False

对笛卡尔乘积的结果进行True/False判断,即对on c.customerid=o.customerid  on c.customerid=o.customerid  and c.city='Madrid',实际上从结果上看这两条语句没什么不同,主要是后者的c.city=’Madrid’未起到任何作用。

3.         然后进行Left Outer操作

Left Outer环节中,因为都是使用customer为基表,在此结果中又把客户MRPHS加了回来,这就是第一条语句会多出来一条记录的原因。

4.         然后进行Where条件解析

第一条语句没有where条件,而第二条语句继续进行where语句解析,又把客户MRPHS删除了。

请使用浏览器的分享功能分享到微信等