
SQL与其他编程语言不同的最明显特征是代码的处理顺序. 在大量编程语言中,代码按编码顺序进行处理,但是在SQL语言中,要处理的第一个子句是FROM子句. 尽管SELECT语句首先出现,但几乎总是在最后处理.
每个步骤都会生成一个虚拟表,用作下一步的输入. 这些虚拟表对调用者不可用(客户端应用程序或外部查询). 仅将在上一步中生成的表返回给调用方. 如果在查询中未指定子句,则将跳过相应的步骤. 以下是与SQL Server 2000和SQL Server 2005对应的逻辑步骤的简要说明.
(8)选择(9)不同(11)
(1)来自[left_table]
(3)
(2)打开
(4)在
(5)GROUP BY
(6)WITH
(7)具有
(10)ORDER BY
逻辑查询处理阶段简介
FROM: 对FROM子句中的前两个表执行笛卡尔乘积(交叉联接),以生成虚拟表VT1 ON: ON过滤器应用于VT1. 只有那些使
注意: 步骤10,根据ORDER BY子句中的列列表,对上一步返回的行进行排序,并返回游标VC10. 此步骤是可以使用SELECT列表中的列别名的第一步,也是唯一的步骤. 此步骤与其他步骤的不同之处在于它不返回有效表,而是返回游标. SQL基于集合论. 集合不预先对其行进行排序,它只是成员的逻辑集合sql语句多个条件查询,成员的顺序无关紧要. 对表进行排序的查询可以返回一个对象,该对象包含以特定物理顺序组织的行. ANSI将此类对象称为游标. 理解此步骤是正确理解SQL的基础.
因为此步骤不返回表(而不是游标),所以使用ORDER BY子句的查询不能用作表表达式. 表表达式包括: 视图,内联表值函数,子查询,派生表和公共表达式. 它的结果必须返回到希望获得物理记录的客户端应用程序. 例如,以下派生表查询无效并产生错误:
select *
from(select orderid,customerid from orders order by orderid)
as d
以下视图也会产生错误
create view my_view
as
select *
from orders
order by orderid
在SQL中,表表达式中不允许使用带有ORDER BY子句的查询,但是T-SQL中存在例外(应用了TOP选项).
因此请记住,不要假设表中的行有任何特定顺序. 换句话说,除非您确定要有序的行,否则不要指定ORDER BY子句. 排序是有代价的. SQL Server需要执行有序索引扫描或使用排序运算符.
推荐一段SQL代码: 转置行和列
/ *问题: 假设有一个学生成绩单(tb)如下:
姓名课程分数
张三玉74
张三数学83
张三物理学93
李四玉文74
李思数学84
李思物理94
想要成为(获得以下结果):
名称,语言,数学和物理学
----------------
李思748494
张三748393
-------------------
* /

createtabletb(名称varchar(10),课程varchar(10),score int)
insertintotbvalues('Zhang San','Language',74)
insertintotbvalues('Zhang San','Mathematics',83)
insertintotbvalues('Zhang San','Physics',93)
insertintotbvalues('Li Si','Chinese'sql语句多个条件查询,74)
insertintotbvalues('Li Si','Mathematics',84)
insertintotbvalues('Li Si','Physics',94)
去
-SQLSERVER2000静态SQL,这意味着只有三门课程: 汉语,数学和物理. (下同)
选择名称作为名称,
最大(在“中国”然后得分为0的情况下)语言,
max(当“ mathematics”然后小数则else0end的情况下的课程)数学,
max(当“物理”然后得分为其他时得分的案例过程)物理
fromtb
分组名称
================================================ ================================================== ===
似乎在编写SQL语句时,我不知道每个关键字的执行顺序. 组织好的SQL语句通常缺乏良好的逻辑. 我感到“拼凑而成”(对不起,如果您的SQL语句经常是“拼凑而成”,那么您是否需要对此进行反思?,呵呵).
这样做对我自己来说真的很酷,但会伤害机器. 服务器还需要在我们混乱的SQL语句中找到要执行的下一个关键字.
效率,因为我们的感觉神经实际上对几秒钟或更短的变化不敏感,所以暂时来说,我们认为自写SQL的顺序无关紧要,“无论如何都没有变化!”,呵呵. 实际上,服务器将为每个SQL分析留出时间. 有关详细记录,您可以查看自己编写的SQL分析时间与按标准顺序编写的SQL分析时间之间的差异.
因此,我建议您在日常工作中以标准顺序编写SQL语句. 一个是的,另一个是实用的,呵呵,但是我认为最重要的是要感到舒适.
标准的SQL解析顺序为:
(1). FROM子句,组合来自不同数据源的数据
(2). WHERE子句,根据指定条件过滤记录
(3). GROUP BY子句,将数据分为多个组
(4). 使用聚合函数进行计算
(5). 使用HAVING子句过滤分组
(6). 计算所有表达式
(7). 使用ORDER BY对结果集进行排序
示例: 在学生分数表(临时命名为tb_Grade)中,根据“候选名称”对“候选名称”内容不为空的记录进行分组,并过滤分组结果,然后选择大于600的“总分数”点.
SQL语句的标准顺序为:
选择候选人的姓名,最高(总分)作为最高总分
来自tb_Grade
候选人姓名不为空
按候选人姓名分组
具有最高(总分)> 600
按最高总分排序
在上面的示例中,SQL语句的执行顺序如下:
(1). 首先执行FROM子句,以从tb_Grade表中的数据源中组装数据
(2). 执行WHERE子句以过滤tb_Grade表中所有非NULL的数据
(3). 执行GROUP BY子句,然后按“学生姓名”列将tb_Grade表分组
(4). 计算max()聚合函数,然后按“总分”以找到总分中的最大值
(5). 执行HAVING子句以筛选总成绩超过600分的课程.

(7). 执行ORDER BY子句,然后按“最大分数”对最终结果进行排序.
================================================ ================================================== ====
SQLServer2005中查询语句的执行顺序
-1.from
-2.on
-3. 外部(加入)
-4.where
-5.group by
-6.cube |汇总
-7.having
-8.select
-9.distinct
-10.order by
-11.top
1. 逻辑查询处理步骤的序号
(8)SELECT(9)DISTINCT(11)
(1)来自
(3)
(2)打开
(4)在
(5)GROUP BY
(6)WITH {CUBE |卷起来}
(7)具有
(10)ORDER BY
每个步骤都会生成一个虚拟表,用作下一步的输入.
只有在上一步中生成的表才返回给调用者.
如果没有子句,请跳过相应的步骤.
1. 发件人:
对FROM子句中的前两个表执行笛卡尔积,以生成虚拟表VT1.
2. 开启:
将ON过滤器应用于VT1. 只有那些使
3. 外(加入):
如果指定了OUTER JOIN,则在保留表中找不到匹配项的行将作为外部行添加到VT2中,以生成VT3.
如果FROM子句包含两个以上的表,请对上一个联接和下一个表生成的结果表重复步骤1至3,直到处理完所有表为止.
4. 将WHERE筛选器应用于VT3. 仅将
5. 分组依据:
根据GROUP BY子句中的列列表将VT4中的行分组,以生成VT5.
6. 多维数据集|汇总:
将超组插入VT5以生成VT6.
7. 拥有
将HAVING过滤器应用于VT6.
只有
注意: hading不能单独使用,having子句用于过滤分组的记录,因此如果有,则必须有一个group by
8. 选择:
处理SELECT列表以生成VT8.
9. 区别:
从VT8中删除重复的行以生成VT9.
10. 排序依据:
根据ORDER BY子句中的列列表对VT9中的行进行排序以生成表(VC10).
11. 页首: 从VC10的开头选择指定的行数或比例,生成表VT11,然后返回到调用方.
注意: 前n个可以实现分页
从员工中选择前20名* ------第一页
从员工中选择前20名*
不在其中的ID号(从员工中选择前20个ID号)------第二页
2. 准备数据
开启NOCOUNT;
使用tempdb;

GO
如果OBJECT_ID('dbo.Orders')不为空
DROP TABLE dbo.Orders;
GO
如果OBJECT_ID('dbo.Customers')不为空
DROP TABLE dbo.Customers;
GO
创建表dbo.Customers
(
customerid CHAR(5)NOT NULL PRIMARY KEY,
城市VARCHAR(10)不为空
);
插入dbo. 客户(客户名,城市)值(“ FISSA”,“马德里”);
插入dbo. 客户(客户名,城市)值(“ FRNDO”,“马德里”);
插入dbo. 客户(客户名,城市)值(“ KRLOS”,“马德里”);
插入dbo. 客户(客户编号,城市)值(“ MRPHS”,“锡安”);
创建表dbo.Orders
(
orderid INT NOT NULL主键,
customerid CHAR(5)空引用客户(customerid)
);
将INSERT插入dbo.Orders(订单ID,客户ID)值(1,'FRNDO');
将INSERT插入dbo.Orders(订单ID,客户ID)值(2,“ FRNDO”);
将INSERT插入dbo.Orders(订单ID,客户ID)值(3,“ KRLOS”);
将INSERT插入dbo.Orders(订单ID,客户ID)值(4,“ KRLOS”);
将INSERT插入dbo.Orders(订单ID,客户ID)值(5,“ KRLOS”);
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-187394-1.html
更新后
那就是死不足惜了
让她永远站最边边上