今天更进一步的学习了数据库单表查询,涉及条件、分组、排序等
select [all|distinct] <目标表达式>
from <表名>
where <条件表达式>
group by 列名 [having <条件表达式>]
order by 列名 [asc|desc];
1、选择表的若干列
查询表时的目标表达式可以是列名、算术表达式、字符串和函数,也可以为查询结果表中的列起别名(指定显示出的列名)
select Sname 姓名,2021-Sage 出生年,'专业',upper(Sdept)
from Student; --专业名转大写
-- 列名 (as) 别名
可以看到,T-SQL在查询时若使用算术表达、字符串或函数,需要指定列挡名,否则显示无列名
查询某一列的数据时,可能会有重复元素,可使用distinct去重(缺省为all,即全部显示)
select Sno as 学号 from SC; --默认为all
select distinct Sno as 学号 from SC; --该列去重
2、选择表的元组(where)
选择条件的表达式在where关键字后填写
2.1 比较运算
比较运算符有=、>、<、>=、<=、!=、<>、!>、!<
同时可使用not搭配上述运算符,相当于取反
select Sname,Sage,Sdept
from Student
where Sdept='CS';
--查询CS专业的学生姓名和年龄
--字符串需要单引号,内容不区分大小写,'CS'和'cs'效果相同
T-SQL中不支持使用not+比较运算符的结构
--查询20岁及以下
/*select Sname,Sage
from Student
where Sage not > 20;*/ --不支持 not+比较运算符
select Sname,Sage
from Student
where Sage !> 20;
涉及空值时,不可使用 =null ,需 is null
使用 =null,相当于查找取值为null的元组,不是空值
2.2 确定范围和集合的查询
SQL语言中逻辑运算符为 and、or、not,相当于C语言中的 &&、||、!
使用 between ··· and ··· 可查询属性在指定范围内的元组,包括两端,可使用not取反
select Sname,Sage
from Student
where Sage between 19 and 21; --19~21岁之间,包括19和21
-- Sage>=19 and Sage<=21
select Sname,Sage
from Student
where Sage not between 19 and 21; --不在19~21岁之间
-- Sage<19 and Sage>21
使用 in 可查询属性在指定集合内的元组,可使用not取反
select Sname,Sdept
from Student
where Sdept in('CS','IS'); --专业是CS、IS
-- Sdept='CS' or Sdept='IS'
select Sname,Sdept
from Student
where Sdept not in('CS','IS'); --专业不是CS、IS
-- Sdept!='CS' and Sdept!='IS'
2.3 模糊查询(like)
like+匹配串,可使用not取反
即字符串匹配查询,使用通配符 %或_ 代替字符
- %,代表任意长度的字符串(可以为0)
select Sname,Sdept
from Student
where Sname like '王%'; --王姓学生
select Sname,Sdept
from Student
where Sname not like '王%'; --非王姓学生
- _,代表任意单个字符
select Sname,Sdept
from Student
where Sname like '欧阳_'; --欧阳姓三字学生
select Sname,Sdept
from Student
where Sname like '欧阳__'; --欧阳姓四字学生
数据库字符集为ASCII时一个汉字需要两个_;字符集为GBK时只需要一个_
查询Sql-Server当前字符集编码方式可使用如下语句:
SELECT COLLATIONPROPERTY('Chinese_PRC_Stroke_CI_AI_KS_WS', 'CodePage');
查询结果为一整数,代表某种字符集的编号
936:简体中文GBK
950:繁体中文BIG5
437:美国/加拿大英语
932:日文
949:韩文
866:俄文
65001:unicode UFT-8
% 和 _ 作为通配符,那么当字符串中需要真正表示百分号和下划线时,需要使用关键字escape定义转码字符
select Sname,Sdept
from Student
where Sname like '王/%' escape'/'; --转义%为普通的百分号
3、排序(order by)
order by用于对查询结果进行排序,需指定排序的属性名,asc升序、desc降序,默认为升序asc
select Sname,Sage,Sno
from Student
where Sdept in('cs','is')
order by Sage; --按年龄升序排序
select Sname,Sage,Sno
from Student
where Sdept in('cs','is')
order by Sage,Sno desc; --年龄相同时按学号(字符串)降序排序
4、聚集函数
聚集函数用于数据的统计功能,只可用于select语句和group by的having语句
- count(*):元组的个数
- count(<列名>):一列中值的个数‘
- sum(<列名>):一列值得总和(该列必须为数值型)
- avg(<列名>):一列值的平均值(该列必须为数值型)
- max(<列名>):一列值的最大值
- min(<列名>):一列值得最小值
这些函数在使用时,可选择统计该列distinct去重后或all所有,默认为all
select count(*) as 学生总数 from Student; --学生总数
select count(Sdept) from Student; --有专业的学生总数
select count(distinct Sno) from SC; --选修了课得学生总数
select avg(Sage) as 平均年龄 from Student; --平均年龄
select max(Sage) as 最大年龄 from Student; --最大年龄
select min(Sage) as 最小年龄 from Student; --最小年龄
使用count(<列名>)查询数量时,会依据元组的该属性是否存在,因此会忽略空值,而使用count(*)查询时不会忽略空值
5、分组(group by)
group by语句可将查询结果按某一列或多列分组,同时可使用having语句搭配聚集函数对每组的数据进一步筛选
select Sdept,count(*) as 人数
from Student
group by Sdept; --各个专业的人数
select Sdept,count(*) as 人数
from Student
group by Sdept having count(*)>1
order by 人数; --查询专业人数大于1的专业,按升序排序
再复习一遍查询语句的格式
select [all|distinct] <目标表达式>
from <表名>
where <条件表达式>
group by 列名 [having <条件表达式>]
order by 列名 [asc|desc];
SQL的查询还是很有意思的,真强大