直接上代码吧,两段sql,sql语句的有些where条件被我删除掉了,不然解释起来太麻烦。
问题就是:注意两段sql绿色的部分,用这个 o 和不用 o 的不用点在哪里?查询结果不一样又是为什么?能讲解一下原理最好,谢谢大家!
一:子查询里面使用 o.UserID,查询结果只有一条.
select o.id Id, c.name CompanyName , u.phone Phone , o.TotalPrice TotalPrice from [order] o left join [dbo].[CompanyInfo] c on o.userid=c.id left join [dbo].[user] u on o.userid=u.id where o.[ID] in ( select top (10) id from ( select id,ROW_NUMBER() over(order by id desc) r from [order] where o.UserID=83863 and TotalPrice>0 ) t where t.r> (0))
二:子查询里面直接使用 UserID,查询结果不止10条
select o.id Id, c.name CompanyName , u.phone Phone , o.TotalPrice TotalPrice from [order] o left join [dbo].[CompanyInfo] c on o.userid=c.id left join [dbo].[user] u on o.userid=u.id where o.[ID] in ( select top (10) id from ( select id,ROW_NUMBER() over(order by id desc) r from [order] where UserID=83863 and TotalPrice>0 ) t where t.r> (0))
大家帮忙看看,这是我优化后的Sql,有没有什么地方有问题,或者可以再优化的,请大家指出,感谢!
WITH orderdetail AS ( select o.id Id,c.name CompanyName ,u.phone Phone o.TotalPrice TotalPrice ,ROW_NUMBER() OVER(order by o.[ID] desc) rownum from [Order] o left join [CompanyInfo] c on o.UserID=c.ID left join [User] u on o.UserID=u.ID where u.ID=83863 and o.TotalPrice>0 ) select * from orderdetail where rownum between 1 and 30
一个用 o 一个不用 o 是两个不同的表,
第一个用 o ,o.userid指的是图中这个位置的.
不用o指的是
这个我知道,我想知道他们在查询的时候会产生什么不同,原理是什么,您能详细讲解一下吗?
@晓菜鸟: 原理.?你可以把两个order看成是两张不同的表,因为它们在这里也是两个不同的表对象.这样应该就好理解一点了吧.?或者说,你有两张表,名子都是order,这里查询分别用的是这两张表.
@创业公司招技术人员.地点在沧州.薪资私聊: 这个我能理解成"自连"吗?加o就是外面的表order要符合o.UserID=83863 且里面的order表的 TotalPrice>0 这样理解可以吗?
不能用o,
额,翔哥,好久不见,说具体点,我理解的意思大概是用o他指向的就是外面那个,查询的时候数据会不对,但是我搞不明白,你具体讲讲呗。
@吴瑞祥
翔哥,人呢?吃饭去了?
@晓菜鸟: 用o的时候挺乱,我也理不清,
1.执行from 连接3个表,左连接
2.执行where,执行子查询,子查询where的时候用外面的表.会有什么问题也是十分不清楚.
这个SQL谁写的?
@吴瑞祥: 一个同事写的,你也认识,接手你发短信的那个。用o的时候查询比较慢,而且数据不对。
@晓菜鸟: 这个子查询感觉上没任何必要......纯粹浪费性能的..
话说发短信那个东西还在维护?我以为我一走那就没人用了
@吴瑞祥: 嗯,是的,我就是为了弄清楚他们的区别,这个sql我已经优化了,发上来你看一下,短信那个没删,目前短信通道还算可以,所以也没怎么维护.
WITH orderdetail AS ( select o.id Id,c.name CompanyName ,u.phone Phone o.TotalPrice TotalPrice ,ROW_NUMBER() OVER(order by o.[ID] desc) rownum from [Order] o left join [CompanyInfo] c on o.UserID=c.ID left join [User] u on o.UserID=u.ID where u.ID=83863 and o.TotalPrice>0 ) select * from orderdetail where rownum between 1 and 30
@晓菜鸟: 嗯,这样写多好啊,把服务器升级成2012吧。有分页语句可以直接用啦。
不用写这么麻烦的分页了
用了O是对外面的order做限制 不用才是里面的查询条件限制
我想知道他们在查询的时候会产生什么不同,原理是什么,您能详细讲解一下吗?
@晓菜鸟: 哦 ,我看过去的不同是:里面对外面的 order表限制(加了o)那么外面表符合where UserID=83863 的数据才会 进行 in判断
对里面的 order 表限制 同理就很好理解了
@风醉: 这个我能理解成"自连"吗?加o就是外面的表order要符合o.UserID=83863 且里面的order表的 TotalPrice>0 这样理解可以吗?
@晓菜鸟: 额,经测试觉得你的理解是正确的,碰到这种混乱的SQL 我建议 自己写个测试语句,对比看看一对多,多对多,多对一 的两个表,在这个查询得到的结果集有什么区别
这个问题我认为就是Order表的自连,在里面用o限制的是外面那个o的范围,里面对外面的 order表限制(加了o),那么外面表符合where UserID=83863 的数据才会 进行 in判断,可以把两个order看成是两张不同的表,因为它们在这里也是两个不同的表对象.这样比较容易理解一些,或者说,你有两张表,名子都是order,这里查询分别用的是这两张表。子查询where的时候用外面的表,具体有什么问题我不是很清楚,但是可以肯定的一点时,这个肯定是不正确的,慢不慢的就不说了。