1.SQL 的解析顺序为:

(1) FROM 子句 组装来自不同数据源的数据

(2) WHERE 子句 基于指定的条件对记录进行筛选

(3) GROUP BY 子句 将数据划分为多个分组

(4) 使用聚合函数进行计算

(5) 使用HAVING子句筛选分组

(6) 计算所有的表达式

(7) 执行窗口函数

(8) SELECT 子句

(9) 使用ORDER BY对结果集进行排序

2.is null和is not null来判断列值是否为空,不能使用=或!=

3.当查询中使用group by时,不必使用distinct,同时使用distinct和group by是多余的

4.union是求并集,集合操作;union all不是集合操作,是多集操作

5.在使用group by和聚集函数count(*)时,select列表中的项,如果没有用作聚集函数(sql五个固有聚集函数:avg,min,max,sum,count)的参数,那么一定要在group by子句中包含它们;在select子句中引入要分组的列通常会增加可读性,但这并不是强制性的。然而,一定不能把不在group by子句中的列放在select列表中

6.查询中使用group by或distinct,则不能按照select中没有的列来使用order by排序

7.任何出现在having子句中,但没有被聚集的属性必须出现在group by子句中,否则查询就被当成是错误的。where子句作用域基本表或视图,having子句作用于组。
包含聚集、group by 或者having子句的查询的含义可通过下述操作序列定义:

(1)根据from子句计算出一个关系

(2)如果出现where子句,where子句的谓词将应用到from子句的结果上

(3)如果出现group by子句,满足where子句的元组通过group by子句形成分组。如果没有group by子句,满足where谓词的整个元组集被当做一个分组

(4)如果出现having子句,他将应用到每个分组上;不满足having子句谓词的分组将被抛弃。

(5)select子句利用剩下的分组产生出查询结果中的元组,即每个分组上应用聚集函数来得到单个关系元组

8.通常查询中不要使用distinct,除非确有必要;对于union而言也是如此,除非确有必要,一般使用union all,而不是union

9.使用not in子句时,注意null值问题,比如:从一个表中查找另一个表没有的值
select * from dept where id not in (select id from new_dept)
如果new_dept中的id存在null值,则查询不会返回任何结果,应该使用
select t1.id from dept t1 where not exists(select null from new_dept t2 where t1.id=t2.id)
对于exists(),它的输入是一个子查询,如果子查询能够返回任何行,那么它就返回TRUE,否则返回FALSE。
所有带in谓词,比较运算符,any和all谓词的子查询都能用带exist谓词的子查询替换

10.相关子查询:子查询中引用外部查询的行
     标量子查询:放在select列表中的子查询(该子查询返回值超过一行会出现错误)

11.avg函数会忽略null值(忽略整行记录),可以使用coalesce函数把null转换为0,再来求平均数

12.max函数可以用来去除null值