加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sqlserver2005T-SQL查询语句的逻辑查询处理1

发布时间:2020-12-12 13:08:21 所属栏目:MsSql教程 来源:网络整理
导读:SQL,T-SQL 1.逻辑查询处理的顺序 (8)select ?(9)distinct (11)top_specifincation select_list (1) from ?left_table (3) join type join right_table (2) on join_condition (4) where where_condition (5) group by group_by_list (6) with {cube | rollup

SQL,T-SQL

1.逻辑查询处理的顺序

(8)select ?(9)distinct (11)<top_specifincation> <select_list>
(1) from ?<left_table>
(3) <join type> join <right_table>
(2) on <join_condition>
(4) where <where_condition>
(5) group by <group_by_list>
(6) with {cube | rollup}
(7) having <having_condition>
(10) order by <order_by_list>
逻辑查询处理的步骤序号

(1)from : 对from子句中的前两个表执行笛卡尔积(交叉连接),生成虚拟表VT1.
(2) on: ?对于VT1应用on筛选器。只有那些使用 <join_condition>为真的行才被插入VT2。
(3) outer(join): 如果指定了outerjoin(与cross join 或inner join不同),保留表中未
找到匹配的行将作为外部行添加到VT2,生成VT3.如果from子句包含两个以上的表,则对上一个
连接生成的结果表和下一个表重复执行步骤1到步骤3,指导处理完所有的表为止。
(4) ?where : 对于VT3应用where筛选器。只有<where_condition>为true的行才被插入VT4。
(5) group ?by :按group by子句中的列列表对于VT4进行分组,生成VT5。
(6) cube | rollup ?把超组插入VT5,生成VT6。
(7)having 对VT6应用having 筛选器。只有使用<having_condition>为true的组才会被插入VT7。
(8)select :处理select列表,生成VT8。
(9) distinct :将重复行从VT8中删除,产生VT9。
(10) order by :将VT9的行按照ORDER BY子句的列列表排序,生成一个游标(vc10)
(11)top :从vc10的开始出选择指定数量或比例的行,生成VT11,并返回给调用者。

set nocount on;

use tempdb;
go


if object_id('dbo.Orders') is not null
?drop table dbo.Orders;
go
if object_id('dbo.Customers') is not null
drop table dbo.Customers;
go


create table dbo.Customers(
customerid char(5) not null primary key,
city varchar(10) not null
);
insert into dbo.Customers(customerid,city)values('FISSA','Madrid');
insert into dbo.Customers(customerid,city)values('FRNDO',city)values('KRLOS',city)values('MRPHS','Zion');


create table dbo.Orders(
orderid int not null primary key,
customerid char(5) null references Customers(customerid)
);


insert into dbo.Orders(orderid,customerid)values(1,'FRNDO');
insert into dbo.Orders(orderid,customerid)values(2,customerid)values(3,'KRLOS');
insert into dbo.Orders(orderid,customerid)values(4,customerid)values(5,customerid)values(6,'MRPHS');
insert into dbo.Orders(orderid,customerid)values(7,null);


--查询订单数来自Madrid且订单数少于3(包括0个订单)的消费者,并包含他们的订单数。
--查询结果按订单数排序,从小到大。
select * from Customers;
select * from Orders;


select c.customerid,count(o.orderid) ordernum
from Customers c left outer join Orders o?
on c.customerid = o.customerid
where c.city ='Madrid'
group by c.customerid
having count(o.orderid)<3
order by ordernum?


--这里涉及到三值逻辑,在sql中除了true、false,之外还有unknown,这三个逻辑。
--对于true 和false的逻辑我们都懂,但是对于unknown的逻辑对于筛选器 on where having?
--则都是认为false处理的,如null和任何值比较都是unknown,筛选器中认为是false
--但是对于check约束检查时候则是认为是true处理,如插入一个null,但是约束null>4可以认为是正确的
select * from Customers where NULL=NULL
--上面的查询结果是空
但是对于unique约束、排序操作和分组操作则是认为两个NULL值是相等的。因此了解unknown的逻辑结果和null在不同
语言元素中被处理的方式是有好处的。


select * from Orders where customerid = null
select * from Orders where customerid is null?
这两句的结果是有明显差异的,通过上面讲的三值逻辑问题,我们可以看出对于null值的判断=并不会产生效果,因为
null=null在筛选器中(on,where,having)中的结果是unknown的,也就是默认为false,因此并不会将结果返回的。
如果想要判断null,可以用is null或者是is not null来处理


2.为什么where筛选器中不能使用select中的别名?
因为参照语句逻辑执行的过程,where子句是第(4)步,而别名是执行到第(8)步之后的,从前后关系看是不可以使用的。
同时为什么where子句中不能使用分组函数等,也是这个道理,因为分组是在where之后执行的,当前虚拟表中没有分组的
内容和操作,因此也是不可以的。


3.聚合函数对于null是忽略的,同时子查询不能作为聚合函数的输入。


4 关于order by 和top的?
--(下面的语句出错)除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
select * from (
select * from Orders order by orderid?
)


--正确的,? ? ? 需要在表表达式后面的括号加一个表的别名,如dd,注意上面那个错误的原因提示
select * from (
select top 5 * from Orders order by orderid

) dd

这是在sqlserver2005技术内幕-T-SQL查询中所学的,虽然sqlserver2005现在看来已经很老了,但是读起这本书还是能够获得很多有用的知识。上面就是,因此

决定对于这一系列的书好好读一读,吸取些养分。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读