SQL进阶提升(疑惑篇order by)-学习sql server2005 step by step(十一)

这篇主要发出两个疑惑,希望有兴趣的人解答,谢谢!

1.newid()疑惑

 

1 create table tb (aa int,bb char(1))
2 insert tb values(1,'A'
)
3 insert tb values(1,'B'
)
4 insert tb values(1,'C'
)
5 insert tb values(1,'D'
)
6

7 insert tb values(2,'E')
8 insert tb values(2,'F'
)
9 insert tb values(2,'G'
)
10 insert tb values(2,'H'
)
11

12 insert tb values(3,'I')
13 insert tb values(3,'J'
)
14 insert tb values(3,'K'
)
15 insert tb values(3,'L'
)
16  ------

17 --SQL1
18  SELECT * FROM tb a
19  WHERE bb IN

20
(
21 SELECT TOP 1 bb FROM
tb
22 WHERE aa=
a.aa
23 ORDER BY NEWID
()
24
)
25

26  --SQL2
27  SELECT * FROM tb a
28  WHERE bb =

29
(
30 SELECT TOP 1 bb FROM
tb
31 WHERE aa=
a.aa
32 ORDER BY NEWID
()
33
)
34

35  drop table tb

多次运行查询语句,运行后看到=与in的区别,用in的时候得出的结果行数会变化,可能是一行,可能是多行,但是用=的时候始终产生得到三行结果

查看了执行计划

--SQL1的执行计划是

2010022416235347.jpg

--SQL2的执行计划是

 

2010022416241438.jpg

希望有人能够详细讲解一下

2.select与order by的冲突

        使用 SELECT 语句,轮询表中的数据,并且处理变量数据时,如果有ORDER BY语句,则得不到想要的结果,但去掉ORDER BY,结果正常。

具体的问题表现参考下面的问题重现代码

问题重现代码

 

1 -- 测试数据
2  
3 DECLARE @T TABLE(id int,value nvarchar(16))
4
5 INSERT INTO @T SELECT
6
7 1, N'好人' UNION ALL SELECT
8
9 2, N'坏人' UNION ALL SELECT
10
11 3, N'吃饭' UNION ALL SELECT
12
13 4, N'垃圾'
14
15
16
17 -- 赋值处理
18
19 DECLARE @str nvarchar(4000)
20
21 SET @str = N'我不是一个好人,也不是垃圾'
22
23 SELECT @str = REPLACE(@str, value, N'<u>' + value + N'</u>')
24
25 FROM @T
26
27 WHERE CHARINDEX(value, @str) > 0
28
29 --ORDER BY CHARINDEX(value, @str) DESC
30
31 SELECT @str
32
33
34
35 /* -- 结果(当赋值处理语句注释掉ORDER BY 时)
36
37 我不是一个<u>好人</u>,也不是<u>垃圾</u>
38
39 -- */
40
41
42
43 /* -- 结果(当赋值处理语句加上ORDER BY 时)
44
45 我不是一个<u>好人</u>,也不是垃圾
46
47 -- */
48

 

问题分析:

问题分析:

两个处理语句的结果不同,通过查看它们的执行计划应该可以看出原因所在,为此,通过

SET SHOWPLAN_ALL ON

输出了两种执行语句的执行计划(仅StmtText部分,有兴趣的读者在自己的电脑上测试的时候,可以去了解其他部分的信息)

StmtText
 Step
 
DECLARE @str nvarchar(4000)  SET @str = N'我不是一个好人,也不是垃圾'
  
 
SELECT @str = REPLACE(@str, value, N'<u>' + value + N'</u>')  FROM @T   WHERE CHARINDEX(value, @str) > 0
 4
 
 
 |--
 Compute Scalar(DEFINE:([Expr1002]=replace([@str], @T.[value], '<u>'+@T.[value]+'</u>')))
 3
 
 
 
 |--
 Filter(WHERE:(charindex(@T.[value], [@str], NULL)>0))
 2
 
 
 
 
 |--
 Table Scan(OBJECT:(@T))
 1
 
 
 
 
 
 
 
 
 
DECLARE @str nvarchar(4000)  SET @str = N'我不是一个好人,也不是垃圾'
  
 
SELECT @str = REPLACE(@str, value, N'<u>' + value + N'</u>')  FROM @T   WHERE CHARINDEX(value, @str) > 0   ORDER BY CHARINDEX(value, @str) DESC
 5
 
 
 |--
 Sort(ORDER BY:([Expr1003] DESC))
 4
 
 
 
 |--
 Compute Scalar(DEFINE:([Expr1002]=replace([@str], @T.[value], '<u>'+@T.[value]+'</u>'), [Expr1003]=charindex(@T.[value], [@str], NULL)))
 3
 
 
 
 
 |--
 Filter(WHERE:(charindex(@T.[value], [@str], NULL)>0))
 2
 
 
 
 
 
 |--
 Table Scan(OBJECT:(@T))
 1
 

从上面的列表可以看出,两种处理的最大差异,在于赋值前,是否有ORDER BY 子句,从一般的理解上,可能会认为是否排序并不重要,但换个角度来看问题,就比较容易理解为什么有ORDER BY子句后得不到我们想要的结果了:

当有ORDER BY子句时,对于SELECT @str = 这种赋值处理,SQL Server认为赋值处理肯定只会保留最后一条记录的处理结果,而ORDER BY子句确定了数据顺序,也就知道最后一条记录是那个,因此只会处理ORDER BY的最后一条记录。(读者可以自行去测试一下,调整ORDER BY顺序,看看结果是否与我的推论相符)

当没有ORDER BY子句时,因为无法确定数据顺序,所以SQL Server必须扫描满足条件的每条数据来得到结果,这样每扫描一条记录都会处理一次,所以结果是我们所预知的

 

问题解决方法:

修改处理语句,使查询优化器使用与我们需要结果一致的执行方法,可以解决这个问题。

对于示例中的处理语句,可以调整如下:

 

1 DECLARE @str nvarchar(4000)
2
3 SET @str = N'我不是一个好人,也不是垃圾'
4
5 SELECT @str = REPLACE(@str, value, N'<u>' + value + N'</u>')
6
7 FROM(
8
9 SELECT TOP 100 PERCENT
10
11 value
12
13 FROM @T
14
15 WHERE CHARINDEX(value, @str) > 0
16
17 ORDER BY CHARINDEX(value, @str) DESC
18
19 )A
20
21 SELECT @str
22

 

 

希望大家踊跃参与解答。

 

转载于:https://www.cnblogs.com/MR_ke/archive/2010/02/24/1672786.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299439.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

钟南山团队在患者粪便中检出新冠活病毒,国家卫健委回应!专家:做好这事很重要...

全世界只有3.14 % 的人关注了青少年数学之旅2月13日下午&#xff0c;在广东省人民政府新闻办召开的疫情防控新闻发布会上&#xff0c;钟南山院士团队成员、广州医科大学国家呼吸疾病重点实验室副主任、教授赵金存介绍&#xff0c;该团队在P3实验室中&#xff0c;在中山大学附属…

CSDN《某一程序员竟然吃过shi?让我们走进他的生活,揭露背后的故事》

CSDN《某一程序员竟然吃过屎&#xff1f;我们走进他的生活&#xff0c;揭露背后的故事》 ——————————接下来让我们走进他的故事 到底是什么原因让他吃屎 这是这位程序员的自曝&#xff0c;我很好奇的不是他吃过屎&#xff0c;我在好奇是啥味的~ 接下来我们开始咨询这…

专升本c语言网课听谁的好_都说塑钢泥比玻璃胶好,填缝永不变黑,师傅却说不好用,听谁的?...

新房装修&#xff0c;我一点不想再用玻璃胶来填补缝隙了。像洗手台、淋浴房、厨房水槽这些地方&#xff0c;不管用多贵多好的玻璃胶&#xff0c;最后&#xff0c;它都会变黑发霉。朋友同我说&#xff0c;可以用塑钢泥替代&#xff0c;20年不发霉~他说&#xff0c;现在很多业主家…

技术分享|明源云天际集成开放平台接口中心基于IdentityServer4的鉴权机制

源宝导读&#xff1a;企业数字化生态建设中为解决集成多样性和资源统一管理的痛点引入企业级网关&#xff0c;网关作为资源访问的大门&#xff0c;身份认证鉴权是其业务的重中之重&#xff0c;本文将介绍企业级网关-天际集成开放平台是如何通过IdentityServer4来做到身份认证和…

设计模式--6大原则--单一职责原则

2019独角兽企业重金招聘Python工程师标准>>> 单一职责原则&#xff08;Single Responsibility Principle&#xff09;&#xff0c;简称SRP。 定义&#xff1a; There should never be more than one reason for a class to change. 应该有且仅有一个原因引起类的变更…

法国为何是伟大数学家的摇篮?

全世界只有3.14 % 的人关注了青少年数学之旅笛卡尔、韦达、帕斯卡、费马、拉格朗日、拉普拉斯、达朗贝尔、勒让德、蒙日、彭赛列、柯西、傅里叶、庞加莱、伽罗华、格罗藤迪克…… 这些令无数大学生“闻风丧胆”的数学家&#xff0c;基本上都诞生于十七至二十世纪的法国。解析几…

(转)WCF教程系列(1)-创建第一个WCF程序

作为微软技术.net 3.5的三大核心技术之一的WCF虽然没有WPF美丽的外观但是它却是我们开发分布式程序的利器但是目前关于WCF方面的资料相当稀少希望我的这一系列文章可以帮助大家尽快入门下面先介绍一下我的开发环境吧操作系统&#xff1a;windows vista business版本编译器&…

03 Files

本章提要-----------------------------------------------组成 oracle 的 8 种主要文件(包括 instance 和 database)instance: parameter file, trace file, alert filedatabase: data file, temp file, control file, redo log file, password file简单概述:parameter file: …

TensorFlow发布全新版本,又会带来哪些变革?

全世界只有3.14 % 的人关注了青少年数学之旅经过几年的发展&#xff0c;深度学习方法摧枯拉朽般地超越了传统方法&#xff0c;成为人工智能领域最热门的技术。之后&#xff0c;谷歌、亚马逊、百度、Facebook 纷纷开源了自己的深度学习框架。而支撑AlphaGo的核心技术架构--Tenso…

码农身份得到正式认证

各位同行的兄弟姐妹们&#xff0c;我们的码农&#xff08;新生代农民工&#xff09;身份已经得到国家正式确认&#xff0c;程序员这个职业也正式并到农民工行列了。现在互联网大厂&#xff0c;大部分程序员都是在做着模式化开发工作&#xff0c;已经没有技术含量了&#xff0c;…

面试字节我被String类的问题给问死了!

“” 是怎么连接字符串的&#xff1f;&#xff08;JDK1.7及以上&#xff09; 总结&#xff1a; 使用 “” 连接字符串时&#xff0c;实际上是使用临时创建的StringBuilder对象来辅助完成的。 对于编译时常量&#xff0c;在编译后直接计算出字符串的值&#xff0c;而不会在运行…

加州大学惊现神操作!物理教授用数学论文摆脱400美元交通罚单,却惨被网友大反转.........

全世界只有3.14 % 的人关注了青少年数学之旅“学好数理化&#xff0c;走遍天下都不怕。”这句从上个世纪八十年代流传下来的金句&#xff0c;至今仍然哺育着理工科的莘莘学子。为了让模友们更好的理解这句话&#xff0c;今天就让小天给你们涨涨姿势&#xff0c;见识一下什么是学…

VMware虚拟机VMDK 快照 数据恢复成功

VMware虚拟机VMDK 快照 数据恢复成功【故障描述】某影院使用的票管理系统安装在一台虚拟中&#xff0c;数据库采用的是Oracle9I,虚拟机在安装好后做了一次快照&#xff0c;期间又做过一次快照&#xff0c;在正常使用过程&#xff0c;虚拟突然崩溃&#xff0c;无法启动&#xff…

[转]两个经典的windbg调试案例,值得学习。

1. 调试Bug的神兵利器&#xff1a;通过WinDbg条件断点收集Log 原文地址&#xff1a;http://blogs.msdn.com/yizhang/archive/2009/03/30/bug-windbg-log.aspx 调试Bug的神兵利器&#xff1a;通过WinDbg条件断点收集Log 前段时间花了几天一直在用WinDbg调试一个比较棘手的Bug。…

设计模式之观察者

观察者模式介绍观察者又名事件订阅者、监听者。观察者模式是一种行为设计模式&#xff0c;允许你定义一种订阅机制&#xff0c;可在对象事件发生时通知多个“观察者”该对象的其他对象。通知目标&#xff1a;拥有一些值得关注的状态的对象。发布者&#xff1a;它要自身的状态改…

二面京东被问到Java 反射,我直呼好家伙,这我不是必过吗?

二面京东被问到Java 反射&#xff0c;我直呼好家伙&#xff0c;这我不是必过吗&#xff1f;用多久我会升职加薪、当上技术总监、迎娶漂亮学姐、走上人生巅峰&#xff01;想想还有点小激动。 好了开始分享面试经历 说说你反射的理解 到底什么是反射呢&#xff1f;&#xff1f;…

通用路由封装(GRE)×××配置

本人没有很好的文采&#xff0c;只能直接配置&#xff0c;有不懂的地方&#xff0c;后面可以联系我&#xff0c;在配置当中&#xff0c;我会尽量在配置命令后面加标注。1、在R1上配置相关的命令R1&#xff08;config&#xff09;#int fa0/0 ---进入以太网fa0/0接口--R1&#…

gridview DataFormatString

转有个时间要在gridview中显示,但是保持着数据库中的是标准时间,很长,而且只需要显示日期,就想要格式化字符串,可是设置了DataFormatString就是不起作用,后来一查,原来要设置"行为"中HtmlEncode false DataFormatString"{0:格式字符串}" 在DataFormatStri…

太神奇了!使用C#实现自动核验健康码:(1)二维码识别

前言因为疫情的原因&#xff0c;无论是进入商场还是医院、车站&#xff0c;都需要出示健康码。现在基本都是采取人工方式核验健康码&#xff0c;看到绿码就通过&#xff0c;否则就禁止进入。但是&#xff0c;单靠人工核验健康码容易造成人员拥堵&#xff0c;增加病毒交叉感染的…

三角形中惊现叛徒!自己胖的像个球,却能成就世界上最快的赛车引擎......

全世界只有3.14 % 的人关注了青少年数学之旅一日&#xff0c;理科生上山寻访禅师。理科生问禅师&#xff1a;“大师&#xff0c;世人为何总嫌我棱角太突出&#xff0c;不合群&#xff01;”禅师思索一阵&#xff0c;掏出数根圆柱铺在地上&#xff0c;在上面搁了一块木板&#x…