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','Madrid');
insert into dbo.Customers(customerid,city)values('KRLOS','Madrid');
insert into dbo.Customers(customerid,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,'FRNDO');
insert into dbo.Orders(orderid,customerid)values(3,'KRLOS');
insert into dbo.Orders(orderid,customerid)values(4,'KRLOS');
insert into dbo.Orders(orderid,customerid)values(5,'KRLOS');
insert into dbo.Orders(orderid,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现在看来已经很老了,但是读起这本书还是能够获得很多有用的知识。上面就是,因此
决定对于这一系列的书好好读一读,吸取些养分。
sql server查询无记录 if sql server2005查询
转载文章标签 sql server查询无记录 if sql server sql 筛选器 ci 文章分类 SQL Server 数据库
-
SQL Server 执行计划3--关联查询
SQL Server执行计划,多表关联查询
Nested Loops Merge Join Hash Match -
SQL Server 账号管理1
SQL Server 账号管理主要包含登录名、用户、架构、角色等管理。通过对账号的管理可以有效的提高数据库系统的安全性,规范运维及使用。注意:登录名是实例下的安全对象,用户、架构及角色是数据库下的安全对象
登录名 用户名 数据库级的主体 SQL Server 级的主体 安全对象 -
SQL server2005新建查询 sql server新建查询菜单在哪
dbForge Studio for SQL Server入门教程:如何创建和编辑查询
SQL server2005新建查询 SQL Server dbForge SQL 数据库