持续积累..
关于 SQL 执行顺序
资料
例句
1 | select * from t_1 join t_2 |
这是一条简单/规范的基本SQL。
注意
SQL三个很重要的位置on/where/having
它们分别对应着 join/from/group 形成后的虚表进行筛选。select部分并不是一开始就执行的,而是表数据确认完毕,只差排序的时候执行的。
并且select中的函数/DISTINCT/TOP也是在select执行阶段执行的聚合函数需Group后才可执行, 普通函数随执行步骤执行(正常执行)
具体顺序
- FROM FROM后面的表标识了这条语句要查询的数据源。和一些子句如,(1-J1)笛卡尔积,(1-J2)ON过滤,(1-J3)添加外部列,所要应用的对象。FROM过程之后会生成一个虚拟表VT1。
(1-J1)笛卡尔积 这个步骤会计算两个相关联表的笛卡尔积(CROSS JOIN) ,生成虚拟表VT1-J1。
(1-J2)ON过滤 这个步骤基于虚拟表VT1-J1这一个虚拟表进行过滤,过滤出所有满足ON 谓词条件的列,生成虚拟表VT1-J2。
(1-J3)添加外部行 如果使用了外连接(外连接才会加入字段/数据)
,保留表中的不符合ON条件的列也会被加入到VT1-J2中,作为外部行,生成虚拟表VT1-J3。此时 不符合ON的会被加入回来
- WHERE 对VT1过程中生成的临时表进行过滤,满足where子句的列被插入到VT2表中。
数据现在还没有被分组,因此现在你不能使用聚合运算-
- GROUP BY 这个子句会把VT2中生成的表按照GROUP BY中的列进行分组。生成VT3表。
每一个分组必须只能返回一行(除非被过滤掉),即每一行整体都无重复,对于没有出现GROUP BY后面的列必须使用聚合函数(如 MAX ,MIN,COUNT,AVG等),保证每一个GROUP只返回一行
- HAVING 这个子句对VT3表中的不同的组进行过滤,满足HAVING条件的子句被加入到VT4表中。
- SELECT 这个子句对SELECT子句中的元素进行处理,生成VT5表。
(5-1)计算表达式 计算SELECT 子句中的表达式,生成VT5-1如果这个sql语句是一个聚合查询,在GROUP BY之后,你只能使用GROUP BY中的列,对不属于GROUP集合中的列必须使用聚合运算
(5-2)DISTINCT 寻找VT5-1中的重复列,并删掉,生成VT5-2
(5-3)TOP 从ORDER BY子句定义的结果中,筛选出符合条件的列。生成VT5-3表 - ORDER BY 从VT5-3中的表中,根据ORDER BY 子句的条件对结果进行排序,生成VC6表。
唯一一个可以使用SELECT子句创建的别名的地方
聚合函数是对一组值执行计算并返回单一的值的函数
1 | SELECT C.customerid, COUNT(O.orderid) AS numorders |
关于 表 Joins
Joins 子句用于结合两个或多个数据库中表的记录, 也就是说是通过某种联系建立表之间的关联, 并形成一张新表
SQL 定义了三种主要类型的连接
交叉连接 ( CROSS JOIN ), 又称 笛卡尔积
会形成庞大的表, 因此慎用。
假设: 表t1(5行数据, 3列), 表t2(4行数据, 2列)
SQL: select * from t1 cross join t2
结果: 数据数量为20行数据(5 * 4), 5列内连接 ( INNER JOIN ), 通常可省略
inner
通过
on
或where
建立表之间的联系或者说表形成的条件
假设: 表t1(5行数据, 3列), 表t2(4行数据, 2列)
SQL: select * from t1 inner join t2 on t1.sid = t2.sid
结果: 查询操作列出与连接条件匹配的数据行, 5列外连接 ( OUTER JOIN )
外连接为内连接的扩展, 主要区别在于哪边为基准, 使用
on
进行数据关联
外连接分为:左外连接
、右外连接
、全外连接
部分SQL语言并不包含全部种类, 例如
SQLite 之包含 左外连接左外连接 ( LEFT JOIN )
假设: 表t1(5行数据, 3列), 表t2(4行数据, 2列)
SQL: select * from t1 left join t2 on t1.sid = t2.sid
结果: 以左表为基准, 将数据按条件进行连接, 左表行全部显示, 若右表没有满足条件的行则显示为NULL, 5列右外连接 ( RIGHT JOIN )
假设: 表t1(5行数据, 3列), 表t2(4行数据, 2列)
SQL: select * from t1 right join t2 on t1.sid = t2.sid
结果: 以右表为基准, 将数据按条件进行连接, 右表行全部显示, 若左表没有满足条件的行则显示为NULL, 5列全外连接 ( FULL JOIN )
假设: 表t1(5行数据, 3列), 表t2(4行数据, 2列)
SQL: select * from t1 full join t2 on t1.sid = t2.sid
结果: 完整的显示两表的数据, 将数据按条件进行连接, 当没有被关联的表中没有存在满足条件的行时, 则显示为NULL, 5列