

千里之行始于足下,我们从基本的官方术语开始,逐步剖析查询语句的各个部分,改变我们对查询简单表面的认识,增强使用SQL的信心和能力,为继续深入学习SQLServer知识打下良好基础。
T-SQL 即Transact-SQL,是MicrosoftSQL Server对ANSI SQL的一种具体实现,SQL的官方发音与单词Sequel相同。
SELECT语句的逻辑处理顺序
从逻辑上讲,SQLServer对查询语句可分为11个阶段,按特定顺序(见图中标号)依次解析。

物理处理顺序
虽然每一条查询语句的逻辑解析是固定的,但是实际执行查询的过程又是富于变化的。受数据规模、查询条件、输出字段等多种因素影响,类似的语句可能采用完全不同的查询方式。掌握查询语句的物理处理规律对分析解决查询性能(效率)十分有用。

FROM子句包含多种运算符,下面我们来介绍JOIN和APPLY。
JOIN
JOIN 所实现的联表操作在SQL语句中十分常见。它细分为INNERJOIN 和OUTERJOIN,OUTER JOIN又分为LEFT/ RIGHT FULL JOIN。

JOIN中的条件大多为相等性判断,比如d.id= e.department_id,但其它逻辑判断同样可以用。
有时会看到如下形式的联表查询,它不使用JOIN关键字,而是把关联条件放到WHERE子句中。这是旧时用法,语义不如JOIN明确,不再推荐使用。

APPLY
APPLY 运算符的作用是为传入的每一个数值,做查询并产生记录,为FROM 子句生成表源。按是否允许NULL记录,可分为CROSSAPPLY和OUTERAPPLY,它们之间的区别逻辑跟INNERJOIN与OUTERJOIN的区别类似。
下面SQL查询每个部门的销售额前两名的员工,以及他们的销售额:


当APPLY产生的表只需要输出一列时,APPLY可以用子查询(嵌套查询)代替;当APPLY表不是由函数产生时,可以用JOIN代替。但是,从语义上来说,APPLY与子查询或JOIN并不相同,实际中应该根据业务的语义选择合适操作符。
将查询结果划分为多个行组,通常用于在每个组上执行一个或多个聚合。SELECT 语句每组返回一行。
使用GROUP意味着返回的结果是按某种条件进行的汇总信息,所以SELECT以及ORDERBY子句中显示的列,只能是被GROUP的列和聚合运算函数。没有用来被GROUP的列,只能作为聚合函数的参数出现。
指定组或聚合的搜索条件,HAVING通常与GROUP BY 子句一起使用,也可以没有GROUP BY的语句中使用。如果未使用GROUP BY,则会有隐式的单一、聚合组。
举例,如果员工数量大于300,则返回员工数量:

除非指定ORDER BY 子句,否则,不能保证在结果集中返回的行的顺序。
由于表中记录存储并非完全按照聚簇主键的顺序排列,所以即使想按主键的顺序输出记录,也不能省略ORDERBY子句。

ORDER BY后可出现的字段有两类:
SELECT子句中列出或定义的字段;
FROM子句中所有表中定义的字段(使用GROUPBY的情况除外)
ORDER BY后可出现的字段需要是明确的,下面两种情况含糊不清而无法排序:
SELECT的输出列中,如果两个或更多列使用同一个列名,那么这个名字不能用来排序;
如果某列名未出现在SELECT输出列表中,但存在于FROM子句的多个表中,这个名字不能用来排序。
INSERT … VALUES
给VALUES提供多组数据,从而一次性添加多条记录。
对于有默认值的列,在VALUES数据中提供DEFAULT以使用默认值。

使用SELECT语句提供添加的数据

使用FROM释放UPDATE/DELETE语句潜能。
FROM子句不仅存在于SELECT,在UPDATE和DELETE语句中依然可以使用,当需要更新或删除的语句中涉及多张表时,就需要引入FROM子句。
FROM子句有多种使用形式,以UPDATE语句举例如下。
FROM中只列出关联表,不包含被更新表

FROM中列出被更新表和关联表
或者

DELETE语句的联表查询格式与UPDATE类似,

CTE即Common TableExpression,指定临时命名的结果集。这派生自简单的查询,并在单个SELECT、INSERT、UPDATE、DELETE 或 MERGE 语句的执行范围内定义。

注意:因为WITH关键字在T-SQL中还有其他用途,为了避免歧义,CTE的WITH子句之前的语句必须用分号结束。
公用表表达式可以包括对自身的引用,这种表达式称为递归公用表表达式。特种特性让我们很容易实现一个循环的效果。
用下面语句产生一个连续的数字序列(sequence)

CTE主题中的第一个查询返回初始值0。
CTE主题中的第二个查询包含一个指向CTE名称的引用,这使得它成为递归成员,并以特殊方式被处理。对CTE名称的递归引用表示上一次调用该CTE返回的结果集,它被不断地调用直到返回空结果集。

举例:计算员工的职位级别:
员工表数据:

职位级别:


虽然在实际中有多种形式的query语句可以执行,但从可移植性和和可读性考虑,尽量使用标准语法。掌握标准语法和SQLServer的日期字面值的标准格式,从开始避免出错可能。
INSERT INTO语句不省略INTO关键字
DELETE FROM语句不省略FROM关键字
日期的字面值用SQLServer标准格式或者ISO格式
- SQL Server标准:20210612 (yyyyMMdd)
- ISO格式:2021-06-12
SQL 语句从功能上可分为三大类:
DML(Data Manipulation Language)
增、删、改、查,这四项只与表内的记录有关的操作
SELECT INSERT / UPDATE / DELETE
DDL(Data Definition Language)
改变表或其他数据库元素结构的语句
- CREATE
- DROP
- ALTER
- TRUNCATE(这个操作不仅清除表的全部记录,还会重置自增列的下一个值,属于结构性改变,故列入DDL)
- RENAME
DCL(Data Control Language, access permission)
控制语句,赋予或者取消账号权限
- GRANT
- REVOKE
InsideMicrosoft SQL Server 2005: T-SQL Querying
作者:Jesse
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Talent Show
更多后续,期待关注!




