1 sql的的特点
sql是声明性语言,它不是过程性语言。
2 sql的执行顺序
sql执行过程中伴随着虚表的生成和在虚表上的操作。
第一步执行的是from
即将多个表和索引读进内存中的缓冲区,生成笛卡尔虚表v1。
第二步执行的是on
将on的条件应用到v1的每一行,筛选出满足条件的行构成虚表v2。
第三步执行的是join
如果是left join,就将前面的表中不在v2中的行加上后面表的null组成新的行加到v2表中,成新的虚表v3;
如果是right join同理。
如果是inner join,不用做什么。
第四步执行的是where
应用where的条件在v3上,筛选出满足条件的行构成新的虚表v4。
第五步执行的是group by
载v4的基础上,将column相同的行排在相邻的地方,构成新的v5表。
第六步,执行having
作用在已经分组的虚表v5上。
第七步执行select
在v5的基础上,如果有聚合函数,执行聚合函数,得到相应的行。得到v6。
第八步执行distinct
select后的行,去掉相同的行。得到v7。
第九步执行order by
按照某行排序,得到最终的表v8。
3 having和where的区别
where子句用于筛选出符合条件的行,在分组前起作用,将不满足where条件的行去掉,在分组之前过滤数据,where条件中不能包含聚合函数。
having子句用于筛选出符合条件的组,在分组后起作用,条件中经常包含聚合函数,使用having条件过滤出特定组,把不满足条件的组丢掉。
4 on和where
on后面是连接条件,where后面是筛选条件,所以on要在where的前面。
所以
from > on > where > group by > having > select > distinct > order by
5 limit
limit m,n,select会返回一个结果,是一个表,现在选取表中第m到第n行,这里的行是从0开始的。
limit m,返回select返回结果的前m行。
6 group by和count
group by a,根据a的不同值对表进行分组,相同的a值的行放在一个分组中。
group by a,b 对a,b进行排列组合,每个组合是一个分组。
count(*)对每个分组进行计数。
所以,下面是固定的用法。
select sex, count(*) as count from students_table group by sex;