[转帖]老外对T-sql的研究:一个问题多种方法.太精彩了!

bluelily22 bluelily22 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
转点东东赚赚人气哈

原文地址:
http://www.winmag.com.cn/forum/itemdisplay.asp?boardid=11&id=503269
感谢这篇文章的作者带我们如此棒的文章

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 子句来达到过滤组的目的.可以达到避免两次表扫描的目的.可以达到更高的性能.我从这篇文章学到了很多的方法,你呢?
...全文

相关推荐

《模式识别与数据挖掘》配套PPT课件

《模式识别与数据挖掘》配套PPT课件

Bryan Ding

科技成果转化项目进场交易前,评估备案环节需要准备哪些材料?_8.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

人工智能通识教育(中职版)课程标准+PPT课件+部分素材+电子活页+在线考核

人工智能通识教育(中职版)课程标准+PPT课件+部分素材+电子活页+在线考核

Bryan Ding

跨境电商供应链管理(AIGC版)课件+教案+参考答案

跨境电商供应链管理(AIGC版)课件+教案+参考答案

Bryan Ding

110KV单电源电网三段式电流保护+距离继电保护整定计算说明报告(23页+6000字)

内容概要:本文是一份关于110kV单电源电网继电保护整定计算的综合性技术报告,全文共23页、约6000字,系统阐述了三段式电流保护与距离保护的设计原理及其整定计算方法。报告深入分析了电力系统在短路故障条件下的电流与阻抗特性,详细推导了电流保护Ⅰ、Ⅱ、Ⅲ段的动作范围、整定原则、灵敏度校验及时间配合机制,确保满足继电保护的选择性、速动性、灵敏性和可靠性“四性”要求。同时,针对长距离或重要输电线路,补充介绍了距离保护的阻抗整定计算方法,并可能结合Matlab进行仿真验证与辅助计算,提升整定结果的准确性与工程实用性。; 适合人群:适用于电气工程及其自动化相关专业的高年级本科生、研究生,以及从事电力系统继电保护设计、运行维护的工程技术人员;要求读者具备电力系统分析、短路计算及继电保护的基础理论知识。; 使用场景及目标:①掌握110kV单电源辐射型电网中三段式电流保护的整定流程与实际计算步骤;②理解距离保护的工作原理及其在复杂工况下的应用优势;③完成实际工程项目的保护配置与整定计算任务,或作为课程设计、毕业设计及科研课题的技术参考资料;④结合Matlab工具实现整定计算的程序化处理与动作特性仿真验证。; 阅读建议:建议读者结合《电力系统继电保护原理》等相关教材同步学习,重点研读整定公式的推导过程与典型算例的计算细节,注意区分电流保护与距离保护的适用场景与配置逻辑,有条件时应利用Matlab等工具对保护动作行为进行建模与仿真,以深化对保护协调配合机制的理解。

欢多天天写代码
评论 3
收藏 已收藏
分享
返回顶部
bluelily22
MS-SQL Server 34,876 成员 254,635 内容