基础版,未考虑性能优化而做出的改变
sql执行顺序
(1)from
(2) on
(3) join
(4) where
(5)group by
(6) avg,sum....
(7)having
(8) select
(9) distinct
(10) order by
整个流程
- 1 from:
- 2 on筛选器:
- 3 join:
- 4 重复1-3步骤
- 5 where筛选器
- 6 group by
- 7 having
- 8 select
- 9 distinct
- 10 order by
- 11 返回结果
from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表table_1
Table A Table B
ID ID
1 3
2 4
笛卡尔乘积后:
AID BID
1 3
1 4
2 3
2 4
on中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 table_2
根据join语句中多个表之间字段的联系,生成一个新的表table_3
几种用法:
INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。
Table A Table B
ID Name ID Name
1 aa 1 bb
2 bb 2 cc
3 cc 3 dd
4 dd 4 ee
inner join: select * from A inner join B on A.name = B.name;
ID Name ID Name
2 bb 1 bb
3 cc 2 cc
4 dd 3 dd
left join: select * from A left join B on A.name = B.name;
ID Name ID Name
1 aa Null Null
2 bb 1 bb
3 cc 2 cc
4 dd 3 dd
right join: select * from A right join B on A.name = B.name;
ID Name ID Name
2 bb 1 bb
3 cc 2 cc
4 dd 3 dd
Null Null 4 ee
from子句中的表数目多余两个表,那么就将table_3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 table_3。
上一步生产的虚拟表引用where筛选器,生成虚拟表table_4
在含有join操作时:on和where的一点区别:
现有两张表A和B:都只有一个字段ID,A数据有4,B的数据有3个
Table A Table B
ID ID
1 1
2 2
3 3
4
1 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID WHERE B.ID<3
AID BID
1 1
2 2
2 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID AND B.ID<3
AID BID
1 1
2 2
3 Null
4 Null
原因: 优先级: on > left join > where
第一条语句的顺序:
a)执行leftjoin A left join B结果:
AID BID
1 1
2 2
3 Null
4 Null
b)执行where B.ID < 2结果: AID BID 1 1 2 2 第二条语句的顺序: a)先执行 A.ID = B.ID and B.ID < 2,得到结果 ID 1 2 b)再执行left join,得到结果 AID BID 1 1 2 2 3 Null 4 Null
group by 子句将中的唯一的值组合成为一组,得到虚拟表table_5。
根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。
Table A
ID Level
1 A
2 A
3 B
4 B
5 B
6 B
7 C
Select count(ID) as Num ,Level from table group by Level
table
Num Level
2 A
4 B
1 C
应用having筛选器,生成table_6。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。
如在6中针对筛选的结果需要进行Num>2的筛选:只能通过having,而不能通过where
Where的执行在group by之前,不能够针对group 不要生成的table进行操作,因此,需要对group by后生成的table进行操作可以使用having对数据进行筛选
处理select子句。将table_6中的在select中出现的列筛选出来。生成table_7
注意:由此可以看出,select是在from之后被执行的,所以在select中使用的别名在where中是不可以被使用的。
应用distinct子句,table_7中移除相同的行,生成table_8。事实上如果应用了group by子句那么distinct是多余的,
原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。
应用order by子句。按照order by 的条件去排序table_8