T-SQL逻辑查询
理解T-SQL的逻辑查询顺序是学习SQL Server的基础。
T-SQL逻辑执行顺序
(8) SELECT (9) DISTINCT (11) <TOP_specification> <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) 执行笛卡尔乘积。如果有多个表JOIN, 则逻辑执行顺序可以理解成: 先执行INNER JOIN, 再执行OUTER JOIN;或者理解成:按表出现的顺序逐个JOIN。当然,实际的执行顺序有赖于实际的执行计划,同一个SQL在不同的“环境”(索引、统计信息等)下,可能产生不同的执行计划。SQL Server的JOIN方式包括:INNER JOIN,LEFT JOIN,RIGHT JOIN,,FULL JOIN,CROSS JOIN,还有值得一提表运算符APPLY:CROSS APPLY,OUTER APPLY。
(2) 应用ON筛选器。注意把过滤条件放在ON和放在WHERE中的区别: 对于INNER JOIN,过滤条件放在哪里结果都正确;对于OUTER JOIN就要注意了:放在ON中,就是先过滤再JOIN,放在WHERE中,就是先JOIN再过滤,得到的结果很可能是不一样的。当然,生成实际的执行计划时,优化器会自动根据实际情况,把SQL中的LEFT JOIN改成INNER JOIN联接,但是,我的建议是:写SQL时,用INNER JOIN还是LEFT JOIN一定要依据实际的业务逻辑。在此还要注意一下三值逻辑:在筛选器中UNKNOW=FALSE, 在CHECK约束中UNKNOW=TRUE,UNIQUE约束, 排序操作和分组操作认为两个NULL是相等的。
(3) 添加外部行。外部联接包含: LEFT,RIGHT,FULL。为了说明“添加外部行”的概念,举个例子:A表有4行记录,B表有3行记录,且与A表中的3行记录一一对应。当A表LEFT JOIN B表时,它们实际上进行了两步操作:1.先INNER JOIN,结果产生3行记录,2.添加外部行:把A表中那1行没有与B表对应的记录“添加”到结果集末尾,最终结果集为4行记录。所以,大家经常说INNER JOIN比LEFT JOIN效率高,原因也就在于此,LEFT JOIN多了一个添加外部行的操作。
(4) 应用WHERE筛选器。再次注意过滤条件放在ON和放在WHERE中的区别:ON在第(2)步被应用, 而WHERE是在第(4)步被应用。
(5) 分组。注意SELECT语句和GROUP语句中的分组字段或表达式要一致,在不影响分组逻辑的前提下,也允许出现小小的不一致,如: SELECT YEAR(orderdate)+1 FROM table_name GROUP BY YEAR(orderdate)。如果用GROUP BY ALL(非标准遗留物),则相当于跳过第(4)步WHERE过滤,测试时可以一用。
(6) 应用CUBE或ROLLUP。注意GROUPING聚合函数在这里的应用:如果是由CUBE或ROLLUP产生的NULL,返回1,否则0。
(7) 应用HAVING筛选器。注意COUNT(*)、COUNT(1)和COUNT(field_name)的区别:前两者无区别,COUNT(field_name)统计时忽略值为NULL的记录。
(8) 处理SELECT列表。注意某些函数只会产生一个值,如GETDATE(),某些函数函数会产生多个值,如NEWID()。
(9) 应用DISTINCT子句。注意DISTINCT应该在TOP之前。
(10)应用ORDER BY子句。唯一一个可利用SELECT列列表中的别名的地方。如果有DISTINCT关键字, ORDER BY中只能出现SELECT列列表中的列。ORDER BY中可以使用数字代表SELECT列表中出现的列,但不推荐。因为ORDER BY只返回游标,所以结果不能用作表表达式(视图、内联表值函数、子查询、派生表、CTE), 但带TOP的选项除外,因为使用TOP后将返回一个结果集, 而并非游标:SELECT * FROM (SELECT TOP(10) * FROM dbo.table_name ORDER BY id DESC) T
(11)应用TOP选项。可以使用WITH TIES,但必须有ORDER BY:除了返回指定条数的记录,再返回与最后一条记录排序相等的所有记录。TOP()中的参数可以是表达式。如果不指定ORDER BY,查询结果顺序将是不确定的,因为生成的执行计划可能不一样,返回的行是SQL Server物理上最先访问到的行。所以说:有赖于排序的结果集一定要加上ORDER BY。
小结
当你写的SQL语法或结果集出现问题时,仔细分析一下T-SQL逻辑执行顺序,就会明白为什么^_^
最新文章
- POJ3250[USACO2006Nov]Bad Hair Day[单调栈]
- Nginx简易配置文件(二)(反向代理)
- linux清理内存命令
- Unity手游之路<;九>;自动寻路Navmesh之高级主题
- MySQL的数据库无法插入中文是怎么回事?
- Gradle basic
- 删除Checkout with Multiple Addresses
- poi操作oracle数据库导出excel文件
- 10.26 noip模拟试题
- A题
- 【水一发next_permutation】poj 1146——ID Codesm
- Muduo 网络编程示例之零:前言
- eval、exec及元类、单例实现的5种方法
- appium+python3+pycharm踩得坑2
- Python_str 的内部功能介绍
- JSON笔记整理
- 磨刀不误砍柴工——统一日志系统 Log4Net/ExceptionLess
- Python并发编程-守护进程
- 【BZOJ4318】OSU! 期望DP
- [Scala]Scala学习笔记五 Object
热门文章
- 03-23 MVC框架(以查询、删除为例)
- Arduino教程资料汇总(8月22日悄悄跟新了一下)
- leetcode341
- 10分钟.Net Core 简单入门教程
- GL_LINES &; GL_LINE_STRIP &; GL_LINE_LOOP
- rocketmq消息存储概述
- memcache分布式的高速缓存系统
- 字符串查找 &#183; Implement strStr()
- mysql的GTID复制和多源复制
- sql查询exist替换in