sql not in 的坑及改写为join

/*我们接着用上次建的两个表。数据如下*/

SQL> select * from l;

STR   V

------ -

left_1 1

left_2 2

left_3 3

left_4 4

 

SQL> select * from r;

STR    V

------- -

right_3 3

right_4 4

right_5 5

right_6 6

 

/*如果要返回l表中有而r表为没有的数据(v=1、2),那么用not in写应该如下*/

SQL> select * from l where v not in(select r.v from r);

STR   V

------ -

left_1 1

left_2 2

 

/*如果r表中v有空值呢*/

SQL> insert into r values(null,null);

1 row inserted

 

/*结果集返回错误*/

SQL> select * from l where v not in(select r.v from r);

STR   V

------ -

 

/*这时要增加条件 r.v is not null*/

SQL> select * from l where v not in(select r.v from r where r.v is not null);

STR   V

------ -

left_1 1

left_2 2

 

/*not exists语句不受null影响,因为not exists中是等值关系*/

SQL> select * from l where not exists(selectnull from r where r.v = l.v);

STR   V

------ -

left_1 1

left_2 2

 

/*以上两种都叫反联接,也可以用join改写解析如下*/

SQL> select l.*,r.* from l left join ron l.v = r.v order by 2;

STR   V STR     V

------ - ------- -

left_1 1        

left_2 2        

left_3 3 right_3 3

left_4 4 right_4 4

 

/*如上所示,l中有,而r中没有的,就是r.v为空的行,那么加上这个条件后,返回的就是所需数据了*/

SQL> select l.* from l left join r onl.v = r.v where r.v is null order by 2;

STR   V

------ -

left_1 1

left_2 2

 

/*如果能前的(+)写法,应该如下,为了便于理解,我们仍分步执行来看*/

SQL> select left_str,left_v from (selectl.str as left_str,l.v as left_v,r.str as right_str,r.v as right_v from l,rwhere l.v = r.v(+) order by 2);

LEFT_STR LEFT_V

-------- ------

left_1  1

left_2  2

left_3  3

left_4  4

 

SQL> select left_str,left_v from (selectl.str as left_str,l.v as left_v,r.str as right_str,r.v as right_v from l,rwhere l.v = r.v(+)) where right_v is null orderby 2;

LEFT_STR LEFT_V

-------- ------

left_1  1

left_2  2

 

/*简化后,语句如下*/

SQL> select l.* from l,r where l.v =r.v(+) and r.v is null order by 2;

STR   V

------ -

left_1 1

left_2 2

 

/*有人把这两种弄混了,写为*/

select l.* from l left join r on (l.v =r.v) and r.v is null order by 2;

/*那么我们把两个表的数据都返回,看结果*/

SQL> select l.*,r.* from l left join ron (l.v = r.v) and r.v is null order by 2;

STR   V STR     V

------ - ------- -

left_1 1        

left_2 2        

left_3 3        

left_4 4        

 

/*以上这句整理一下就是*/

SQL> select l.*,r.* from l left join(select * from r where r.v is null)r on (l.v =r.v) order by 2;

STR   V STR     V

------ - ------- -

left_1 1        

left_2 2        

left_3 3        

left_4 4

 

/*相当于是l与一空行join了*/

SQL> select * from r where r.v is null;

STR    V

------- -

 

SQL>

 

/*对join的方法引申一部,改为full join*/

SQL> select l.*,r.* from l full join ron l.v = r.v order by 2,4;

STR   V STR     V

------ - ------- -

left_1 1        

left_2 2        

left_3 3 right_3 3

left_4 4 right_4 4

         right_5 5

         right_6 6

7 rows selected

 

SQL>

 

/*看上述结果,对别对应l.v为空,与r.v为空就是两个表不匹配的行*/

SQL> select l.*,r.* from l full join ron l.v = r.v where (l.v is null or r.v is null)order by 2,4;

STR   V STR     V

------ - ------- -

left_1 1        

left_2 2        

        right_5 5

        right_6 6

 

SQL>

/*当然,以上语句就不能用(+)改写了*/
---------------------

原文链接:https://blog.csdn.net/jgmydsai/article/details/15810295

posted @ 2019-08-08 11:56  道木先生  阅读(851)  评论(0编辑  收藏  举报