on后and条件会和on条件一样在进行表连接的时候作为两表条件记录匹配查询,其条件针对于left join right join full join查询出来的记录数是没有影响的,会在where执行前先执行。
where条件是对整个关联后的最终查询结果进行条件筛选,会对记录数起到真正的影响。
这两者是没有什么关系的,它们只是先后执行而已,都是看需要使用,在使用inner join时,放在and放在on后面和放在where后面是一样的,因为inner join是内连接,on条件下查询的是两个关联表之间都得有对应的匹配记录,会对最终的查询结果记录数有影响。
举例
学年表:SCHOOLCALENDAR
学期表:SEMESTER
结算表:BALANCE
票据表:BILL
学年表与学期表(一对多,每年有第一学期和第二学期)
结算表与学年表(一对多,每年有多条结算记录)
结算表与票据表(假设:多对多)
需求:查询当前学年的所有BALANCE记录
1.
select ba.STUDENT as id from BALANCE ba
left join SCHOOLCALENDAR sr on ba.SCHOOLYEAR=sr.SCHOOLYEAR left join SEMESTER se on sr.ID=se.SCHOOLCALENDAR
left join BILL b on ba.BILLNO=b.ID where se.ISCURRENT='Y' 每年有第一学期和第二学期,使用left join关联SEMESTER会导致记录增倍,但是在where后面加了当前学期限制se.ISCURRENT='Y' ,去除了无用的翻倍查询记录数,即使后面再使用left join关联BILL表,会造成BALANCE和BILL多对多会导致查询记录更多,但是已经用了se.ISCURRENT='Y'限制了,把所有的没有用的数据都去除了,即使关联出更多的记录也没事。
2.
select ba.STUDENT as id from BALANCE ba
left join SCHOOLCALENDAR sr on ba.SCHOOLYEAR=sr.SCHOOLYEAR left join SEMESTER se on sr.ID=se.SCHOOLCALENDAR and se.ISCURRENT='Y'
left join BILL b on ba.BILLNO=b.ID 如果这里把se.ISCURRENT='Y'条件放在on 条件后面的话,会导致BALANCE表的非当前学年的记录也一起查出来,因为使用的是left join,左边记录会全部显示,on后条件只是限制了右表能与左边匹配的记录,虽然数据不会翻倍,但是左表查询出了多余的数据。
3.
select ba.STUDENT as id from BALANCE ba
left join SCHOOLCALENDAR sr on ba.SCHOOLYEAR=sr.SCHOOLYEAR inner join SEMESTER se on sr.ID=se.SCHOOLCALENDAR and se.ISCURRENT='Y'
left join BILL b on ba.BILLNO=b.ID
如果这里把se.ISCURRENT='Y'条件放在on 条件后面的话,并且把left join改成inner join,那最终的结果就和示例1的结果是一样的,因为inner join是必须左表右表记录条件都匹配的记录才会查询出来,会先将BALANCE非当前学年的记录先去除再和BILL进行关联查询。
总结:where后的条件和left join或者right join on后的条件查询出来的记录数是不一样的,和inner join on后的条件查询出来的记录数是一样的。where后的条件和inner join on后的条件区别就在于where是先将所有记录数查询出来再进行筛选,inner join on后的条件是先筛选再继续关联,先后顺序不同。