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。希望大佬能够赐教。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server ,`EXISTS` 是一个用于检查是否存在符合特定条件的记录的逻辑运算符。`EXISTS` 返回一个布尔值,即 `TRUE` 或 `FALSE`,表示查询结果集是否包含匹配条件的记录。下面是 `EXISTS` 的详细用法: 1. 基本语法: ```sql SELECT column_name(s) FROM table_name WHERE EXISTS (SELECT column_name FROM table_name WHERE condition); ``` 2. 示例: 假设有两个表,分别为 `customers` 和 `orders`, `customers` 表包含了所有客户的信息,而 `orders` 表包含了所有的订单信息。我们需要查询所有已经下过订单的客户的姓名和地址,可以使用以下 SQL 语句: ```sql SELECT customerName, address FROM customers WHERE EXISTS (SELECT * FROM orders WHERE orders.customerID = customers.customerID); ``` 在上面的 SQL 语句,`EXISTS` 子查询的条件是查找 `orders` 表的所有记录,其 `orders.customerID = customers.customerID` 表示连接两个表的条件,即匹配两个表的 `customerID` 列。如果 `EXISTS` 子查询返回 `TRUE`,则 `customerName` 和 `address` 列的值会被返回。 3. 注意事项: - `EXISTS` 子查询必须包含一个 `SELECT` 语句,该语句必须返回一个结果集。 - `EXISTS` 子查询的条件必须使用外部查询的列或表。 - `EXISTS` 子查询的 `SELECT` 语句可以是任何有效的 T-SQL 查询语句,包括 `SELECT *`。 - `EXISTS` 子查询的条件可以包含任何有效的 T-SQL 表达式和运算符。 - `EXISTS` 的性能比使用 `JOIN` 进行连接查询要高,特别是在查询大型数据集时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值