在进行两个表乃至多个表进行联接时需要on条件进行匹配,很多时候我们会对过滤条件放在on还是where中心存疑惑。一般来讲,在外联接中on是两个表进行关联的匹配条件,在该条件匹配下会生成一个虚拟表。
如:left join在根据on中的条件联接表时,即使左边的表(保留表)和右边的表(非保留表)存在不匹配项(即外部行),联接后的结果也会完整保留左边表的内容,只是外部行在非保留表中的列都是NULL,即left join得到的结果包括内部行(匹配项)和外部行(不匹配项)。而where子句是在from子句进行处理的,这个时候如果在where子句中指定过滤条件,将得到最终需要的结果。
一言概之,on子句过滤条件不是最终的,而where子句过滤条件却是最终的!
两个表的基本信息分别如下(顾客信息表/订单表):
当查询要求为:返回在2007年2月12日下过订单的客户,以及他们的订单,同时也返回在2007年2月12日没有下过订单的客户。
select c.custid,c.companyname,o.orderid,o.orderdatefrom sales.customers as cleft join sales.orders as oon o.custid=c.custidand o.orderdate='20070212';
根据红线框的结果,将过滤条件orderdate='20070212'放在on子句中返回了在这一天下过订单的客户以及没有下订单的客户,同时注意到上图右下脚结果集总共有91行,也就是外联结的结果留下的是保留表的数据,未匹配的非保留表列值为NULL。
如果查询的要求前半句不变,后半句改为“不返回在2007年2月12日没有下过单的客户”。这时就需要将过滤条件orderdate=‘20070212’放在where子句中。最终的结果只有在当天没下单的客户数据。
select c.custid,c.companyname,o.orderid,o.orderdatefrom sales.customers as cleft join sales.orders as oon o.custid=c.custidwhere o.orderdate='20070212';