sql server 中,join,in,exists学习

在sql 中,join /in /exists 都可以用来实现,“查询A表中在(或者不在)B表中的记录”,这种查询,在查询的两个表大小相当的情况下,3种查询方式的执行时间通常是:
exists <= in <= join

当表中字段允许NULL时,not in 的方式最慢;
not exists <= left join <= not in

JOIN 和 IN

select * from A where id in(select id from B)
select * from A left join B on A.id = B.id
使用join也可以实现这种功能(“查询A表中在(或者不在)B表中的记录”),但是往往吃力不讨好,因为还需要处理NULL,JOIN的使用场景是连接两个表,而不是判断一个表的记录是否在另一个表中

in 和 exists

select * from A where id in(select id from B)

但是,通常情况下,两个表中数据是一个较大,一个较小,这种情况下,
in适合子查询表B 数据小的情况;
exists适合子查询表B 数据大的情况

原因:in在查询的时候,先查子查询的表B,然后将内表和外表做一个笛卡尔积,然后按照条件筛选,所以子查询表比较小的时候,in的速度较快;
而exists 是对外表A做loop循环,每次loop循环再对内表B进行查询,即我们先查询的不是子查询B的内容,而是查我们的主查询的表A,所以子查询表数据比较大的时候,exists的速度较快

not in 和 not exists

select * from A where id not in(select id from B)

无论哪个表大,not exists 总是比 not in 执行效率高

原因:not in没有用到索引,同时,内外表都要进行全表扫描;
而 exists的子查询依然可以使用索引。

要选出某一列不重复,某一列作为选择条件,其他列正常输出的情况.

如下面的表table:

Id  Name  Class Count  Date

 1   苹果    水果    10     2011-7-1

 1   桔子    水果    20     2011-7-2

 1   香蕉    水果    15     2011-7-3

 2   白菜    蔬菜    12     2011-7-1

 2   青菜    蔬菜    19     2011-7-2

如果想要得到下面的结果:(Id唯一,Date选最近的一次)

1   香蕉    水果    15     2011-7-3

2   青菜    蔬菜    19     2011-7-2

有三种sql可以达到

方法一:

select  Id,Name,Class,Count,Date
from Fruit as f
where not exists (select Id,Name,Class,Count,Date
                from Fruit 
                where Id=f.Id and Date>f.Date)

方法儿:配合视图

create view NewFruit as
select Id,MAX(Date) as NewDate
from Fruit as f
group by Id 

select  Id,Name,Class,Count,Date
from Fruit as f
where exists (select 1 from NewFruit where NewFruit.NewDate=f.Date and NewFruit.Id=f.Id)

方法三:
select Fruit.Id,Name,Class,Count,Date
from Fruit right join (select  Id,MAX(Date) as newDate
                        from Fruit 
                        group by id ) as newf 
on Fruit.Date = newf.newDate and Fruit.Id=newf.Id

三种sql的执行效率还没高明白,我自己查看执行时间,估计是数据表太小了,查询的时间都是0。希望大佬能够赐教。

猜你喜欢

转载自blog.csdn.net/KoHsin_/article/details/102901858