邮件订阅
5ucms仿站,老外对T-sql的研究:一个问题多种方法
作者: 来源: 日期:2018/4/13 17:01:48 浏览量:3(滞后) 人气:LOADING...(实时) 【

5ucms仿站,老外对T-sql的研究:一个问题多种方法

T-SQL允许你使用不同的方法解决一个问题.有的时候,尽管选择不是那么明显,但是却可以让你得到令人满意的和快乐的惊奇.下边让我们解读Dr. Tom Moreau对同一问题不同的可能性的探索.可能我们可以在那些不同的方法之中发现一些珍贵的东西.

 

让我们以我们的老朋友Northwind数据库为例,这里我们用到的是[order details]表,这个表是一个定单的明细表,和order表是多对一的关系.也就是一个定单对应多个订购的产品.假设你想得到每个定单订购的总价值,但是不包括59号产品.Listing 1给了我们第一种解法:

 

select            OrderID,sum (Quantity * UnitPrice) value            from [Order Details] o1 where ProductID <> 59            group by OrderID

 

 

 

上边的语句很简单,它排除掉了59号产品的定单明细条目,然后进行分组统计.但是如果我们需要忽略掉订购59号产品的定单呢?也就是说我们要统计没有包含59号产品的定单的价值.你想到了WHERE, NOT EXIST(S)关键词了吗?Listing 2给了我们第二种方法:

 

select            o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value            from [Order Details] o1            where not exists            (            select            *            from [Order Details] o2            where            o2.OrderID = o1.OrderID            and o2.ProductID = 59            )            group by o1.OrderID

 

 

 

如果你不喜欢用exist的话,你可以转化成使用not in:

 

Listing 3            select            o1.OrderID,sum (o1.Quantity * o1.UnitPrice) value            from [Order Details] o1            where 59 not in            (            select ProductID from            [Order Details] o2            where o2.OrderID = o1.OrderID            )            group by o1.OrderID

 

 

 

尽管Listing 1不满足我们现在的查询条件.但是从性能发面考虑,Listing 1还是最好的,因为它只用到了一次表的扫描.而后边的两个查询都是用到了相关子查询,如果你查看查询计划就回看到,他们都涉及到了两次表的扫描.如果你曾经在 T-SQL用过交叉表查询的话,你就不会对聚集函数里边的case结构陌生.现在我们就把这个非常有趣的方法应用到我们的问题中来:

 

Listing 4            select            OrderID,sum (Quantity * UnitPrice) value            from            [Order Details] o1            group by OrderID            having            sum (case when ProductID = 59 then 1 else 0 end) = 0

 

 

 

HAVING子句起到了对分组的结果进行过滤的作用.如果没有包含59号产品,就会出现0=0,显然这是满足条件的.如果包含了59号产品的订购,就会出现n=0(n<>0),这样的定单就回被过滤掉.查看执行计划你就回发现是一次表的扫描,非常棒!

 

再来举一个例子:我们这回用到的表是order表,假设我们要统计只通过一个雇员雇员下定单的顾客.你可以想到用子查询not exist来实现:

 

select distinct            o1.CustomerID            from            Orders o1            where not exists            (            select * from Orders o2            where o2.CustomerID = o1.CustomerID            and o2.EmployeeID <> o1.EmployeeID            )

 

 

 

同样的,这个语句可以通过带有HAVING子句的分组来实现.

 

 

Listing 6            select CustomerID from            Orders group by CustomerID            having            min (EmployeeID) = max (EmployeeID)

 

 

 

另一种方法:

 

Listing 7            select CustomerID from            Orders group by CustomerID            having            count (distinct EmployeeID) = 1

 

 

 

 

Listing 6和Listing 7查询消耗都要小于Listing 5.相比Listing 5的两次表扫描,他们只进行一次表的扫描.而Listing 6的损耗还要稍微小于Listing 7.但是,Listing 7的一个显著的特点就是它可以适应到一个顾客对应两个雇员,三个雇员......

其实大家可能现在明白了这篇文章将的是什么?它就是教我们怎么用having 子句来达到过滤组的目的.可以达到避免两次表扫描的目的.可以达到更高的性能.我从这篇文章学到了很多的方法,你呢?


欢迎您访问www.5ucms.org

本站推荐: 5ucms模板下载 5ucms插件下载 仿站联系Q3876307       [复制给好友] [打印] [关闭] [返回] [顶部]
上一篇:5ucms模版,ORACLE8I转换数据到SQL SERVER数据库
下一篇:5ucms仿站,利用MSSQL sp自制未公开的加密函数
本站声明:本网站所载文章等内容,目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权及其它问题,请在30日内与本网联系(Email:3876307#qq.com),我们将在第一时间删除内容。若原创内容转载请注明出处。
5ucms仿站,老外对T-sql的研究:一个问题多种方法的关键词:
评论信息
相关分类
本周热门
本月热门
关于我们 - 版权/免责 申明 - 建站服务 - 网站地图 - 稿件投递 - 联系我们 - 5ucms
Copyright © 2008-2015 www.5ucms.org