4.2 单表查询
4.2.1 列名(表名)的别名(as 可以不加)
给列名取别名既可以加 as 也可以不加。 (2008 - Sage、lower(Sdept)等可计算但无列名,需要指定列名)
原列名既可以作为判断条件,也可以排序;列名的别名只能用作排序,不能用作判断条件。
表名也可以有别名,给表名取别名既可以加 as 也可以不加;用表名或者表名的别名来引用列名,既可以排序也可以用作判断条件。(用表名或者表名的别名来引用列名的别名,既不可以排序也不可以作为判断条件)
4.2.2 消除重复行 distinct
select distinct Sno from SC
消除取值重复的行,关键字是 distinct(默认缺损值是 ALL),这个是针对某一行而不是某一个字段。(也就是说只有当各行之间的每一个字段都完全相同才算是重复的)
4.2.3 比较运算符、not 运算符
select distinct Sno from SC where not grade < 60
比较运算符: > 、>= 、< 、<= 、= 、!= 、<> 、!> 、!<
not 运算符:针对的是某一个逻辑表达式(bool 表达式),而不是针对一个符号(比如 grade not < 60)。
所以,运算符 not 可以与比较运算符同用,对条件求非,比如 not grade < 60
4.2.4 确定取值范围 between…and…
select Sname,Sage from student where sage not between 22 and 20 --这样是查不到的
确定取值范围: between … and…、 not between … and…
注意: between A and B 相当于 >= A and <= B,顺序不能错。
4.2.5 确定集合 in、not in
select Sname,Sage,sdept from student where sdept in ('CS','ma')
注意:要加括号的。
4.2.6 模糊查询 like
select *from student where sno= '95001'
select *from student where sno like '95001'
select *from student where sname like '刘%'
select *from student where sname like '刘_'
select *from student where sno like '9500_'
select *from student where sname like '_呈%'
select *from student where sname not like '刘%'
select *from course where cname like 'DB\_M' escape '\'
select *from course where cname like 'MA\%S' escape '\'
select *from course where cname like 'MA%K__'
字符匹配: [not] like % _ escept
当 like 后面的字符串没有包含通配符的时候,like 就是 = 。
_ :代表一个字符.默认每一个字符(数值,字母,汉字)采用ascii进行编码的.但是不管用什么方式进行编码,_代表的是一个字符,而不是一个字节
escape 定义某一个字符,这个字符后面紧跟的通配符是不起通配作用的,当 like 比较的时候会忽略字符串中的 escape 定义某一个字符,而把其后的通配符当成一个普通的字符。
4.2.7 涉及空值 null 的查询
select *from student where sname = ''
select *from student where ssex is null
select *from student where sname is not null
涉及空值的查询:is not null 。
当是空值的时候只能用IS来判断,其他的都不可以。
null表示什么都没有,而''表示的是长度为零的字符串。(null与任何类型的值进行算术运算的结果都为null )
4.2.8 多重条件查询 and、or
and 的优先级比or高,但是()可以改变优先级别
4.2.9 对查询结果进行排序
select * from SC where cno= '3' order by grade desc
select * from SC order by sno,grade
排序order by asc/desc (asc 是升序,是默认的缺损值,desc是降序的)
order by a,b,c,d 像这种按照多个字段进行的排序,先按照第一个字段排序,再按照第二个字段排序,以此类推,但是第二个字段的排序是在第一个的基础上进行的,它不会去打乱第一个排序的,
第一个排序其实就已经分成组了,第二个排序是在第一个排序的各个小组里面进行的排序。
4.2.10 聚集函数(count、avg、sum、max、min)
select * from student
select count(*)from student --不能加 distinct 或者 all
select count(all sno) num from student
select count(distinct sno) num from student
select avg(distinct sage)from student --必须是数字,非null值的加和除以非null值的个数
select sum(distinct sage)from student --必须是数字,非null值的加和
select max(distinct sno)from student --只要是可以比较大小的就可以,如果该列全是null,那么结果也是null
select min(distinct sno)from student --只要是可以比较大小的就可以,如果该列全是null,那么结果也是null
对于这些集函数,dinstinct表示消除了重复的行,而默认缺损为all
4.2.11 分组查询 group by
select * from sc
select cno from sc group by cno --以某一列分组并筛选某一列就可以查看到该列所具有的不同的值
--分组之后,每一组只会有一行,并且一组中只取一个值,所以如果要在查询结果中加入其他的列,要保证这些列在一组中只有一个值。
select cno,sno from sc group by cno,sno --分组是不会排序的
select cno,sno from sc group by cno,sno order by cno
select cno,count(sno)from sc group by cno
select sno,count(cno) cnoNum --选3门课以上的学生的选课数
from sc group by sno
having count(distinct cno) >= 3
select cno,count(sno) from sc where cno > 1 group by cno,sno
having count(sno)>0 order by cno
上面的 sql 语句执行的顺序是:先分组,然后查询计算,然后在查询的结果中判断 where 和 having 条件,最后排序。
分组与不分组的区别是:
不分组的时候,(如果是多表的话,先要去连接)先查询,然后在查询结果中按照where子句的条件来筛选。
而分组的时候,(如果是多表的话,先要去连接)是先分组,然后再执行查询,然后在查询结果中按照where子句和having子句的条件来筛选。
Having后面的聚集函数是对每一最小组(按照 group by 后面的所有列进行的分组,是所有列而非某一列分组)的那些行进行运算的。
另外,having 后面也可以对某列进行非聚集函数的条件判断,这种判断也是针对每一最小组的那些行。
select top 10 a.sno,count(distinct cno) cno_num
from student as a,sc as b
where a.sno = b.sno and a.sno ='95001'
group by a.sno
having count(distinct cno)>= 2
order by a.sno
查询的执行步骤:
先连接,然后按照条件去分组,然后按照组查询,先查询第一组(第一行),然后用where子句和having子句的条件来筛选,满足条件就保留,否则就舍去,然后查询第二行......,最后在查询出的结果中排序,然后在排好序的结果中去求top n。
小结:
1、分组是按照某个列来进行分组的,最后在该列中列值相同的就是一组了,group by a,b,c先按照a进行分组,在按照a分好的每一组里面,再按照b进行分组,即保留了最开始的组,然后在按照b分好的组里面再按照c进行分组,以此类推......
2、分组是不会排序的,排序和分组是两个独立的过程,排序是在分组查询之后,在最终的满足各种条件的查询结果里面来排序.
3、如果在分组的时候要查询某些字段,那么一定要保证在最小组中的该字段是绝对唯一的,因为每一个最小组最后只会有一行记录,有时候,用户知道是绝对的唯一的,但是计算机不知道,所以在这种情况下必要的时候
可以再按照该字段进行一次分组,或者使用聚集函数。在使用集函数进行运算的时候,是对最小的组进行计算.
4、没有分组的时候判断条件用where,分组之后对于某一组的聚集函数结果的判断条件是having,一般用于聚集函数count,分组后对于某一个字段的判断还是用where