▶ 别名
select * from userInfo as u -- 给表取别名
select UserName as Name, UserPwd as Pwd
from userInfo -- 给列(属性)取别名
※ 注:as 均可省略
▶ 查询列的数据
-- 就是上面的命令
-- 分别是查询全部列(*),查询指定列
▶ 查询前几行的数据(top)
select top 1 *
from userInfo -- 查询第一行的所有列的数据
select top 50 percent *
from userInfo -- 查询前50%行的所有列的数据
▶ 排序(order by)
select * from userInfo
order by UserAge asc/desc(升序/降序) -- 按照UserPwd排序(默认升序)
select * from userInfo
order by UserAge asc, UserId desc -- 先按照UserAge升序排序,在其相同的情况下根据UserId降序排序
▶ 消除重复行(distinct)
select distinct UserAge from userInfo -- 列名前加distinct
▶ 条件查询(where)
• 比较运算符:=(单等于), >, <, >=, <=, !=(也可写成<>)
• between…and… 表示在一个连续的范围内(闭区间)
• in 表示在一个非连续的范围内
• 逻辑运算符:and ,or, not
☀ 模糊查询(like):用于处理字符串类型的值
%
0到多个任意字符
_
1个任意字符
[]
1个范围内的字符
^
写在[]内部的开头,表示"非"
※ 注:%, _写在[ ]中转义成本义; [2-9]表示连续范围
select UserName from userInfo
where UserAge = 12 -- 查询年龄为12的user的姓名
select * from userInfo
where UserId between 1 and 3 -- 查询编号1~3的user的所有信息
select * from userInfo
where UserId in (1, 3) -- 查询编号1或3的user的所有信息
--模糊
select * from userInfo
where UserName like '%Lo%' -- 模糊查询名字带"Lo"的User的全部信息
select * from userInfo
where UserAge like '1[^234]' -- 模糊查询年龄第一位为1,第二位数不是234的user的全部信息(注意[]是1个字符,就很好理解了)
※ 注:where UserEmail = null (✘)
where UserEmail is null(✔)
▶ 连接查询(当需要的结果从多张表中取时)
关键 ☆:那些表
?关系
?
-- 连接查询格式(inner表示内连接,关键字join加表名,on加条件)
select *
from StudentInfo
inner join ClassInfo on cid = cId
-- 如果两个属性名称相同,需要加表名前缀来区分
select *
from StudentInfo
inner join ClassInfo on StudentInfo.cId = ClassInfo.cId
-- 一个典例:查询学生姓名及所在班级名称
select si.sName, ci.cName
from StudentInfo as si
inner join ClassInfo as ci on si.cId=ci.cId
※ 注(外连接都简写了一个outer):
内连接 inner join
左外连接 left join 保留左表中特有的数据
右外连接 right join 保留右表中特有的数据
完全外连接 full join 左右边特有的数据都保留
▶ 多表连接
-- 一个典例:打印学生姓名,科目名称,成绩
-- 找到哪些表( StudentInfo, SubjectInfo ) → ScoreInfo
-- 找到哪些关系 ScoreInfo.stuId=StudentInfo.stuId , ScoreInfo.subId=SubjectInfo.subId
select stu.sName,sub.sName,score.scoreValue
from ScoreInfo as score
inner join StudentInfo as stu on score.stuId=stu.stuId
inner join SubjectInfo as sub on score.subId=sub.subId
-- 注意一个连接逻辑:每次多写一行join,是与上面已经连接好的表连接在一起,而不是from紧跟的那个表
▶ 聚合函数(对行数据进行合并,简单讲就是统计)
COUNT(计数)
select COUNT(*) from UserInfo -- 只有COUNT能用(*),其他聚合函数一般是对某一列的(数字)数据进行处理
select COUNT(*) as count_column from UserInfo
where Id=1 -- 给该列取个别名;where加上条件
-- 注意:null 是不计入数的
MAX(最大值),MIN(最小值),AVG(平均数),SUM(求和)
-- demo1
select MAX(scoreValue) from ScoreInfo
where subId = 2 -- 科目编号为2的最高分
-- demo2
select AVG(scoreValue) from ScoreInfo
inner join SubjectInfo on SubjectInfo.subId=scoreInfo.subId
where subName = '语文' -- 查询语文成绩的平均分(★思路:找表--ScoreInfo,SubjectInfo;找关系:SubjectInfo.subId=scoreInfo.subId)
再说一遍,聚合中NULL不参与计算
▶ 开窗函数 over()
将统计信息分布到行中
over() 用在聚合函数之后(将被聚合的数据还原到每一行中)
over()一般与聚合函数、排名函数结合使用
select *, AVG(UserAge) over()
from userInfo
效果如下↓(打印出表的所有信息,并将平均年龄打印在每一行):
▶ 分组(group by)
select cls, COUNT(*) as num
from userInfo
group by cls -- 根据班级分组并打印各组人数
select cls, gender, COUNT(*) as num
from userInfo
group by cls, gender -- 根据班级分组后,再把每个班分为男女两组
-- 先分男女再分班级也一样,也就是gender和cls的位置无所谓
注 :
我们按照班级分组,除班级以外的具体信息(比如姓名,年龄)都被屏蔽了;只有分组依据(班级)还能再使用
虽然每一组的具体数据被屏蔽了,无法展示,但这个组的数据信息还能够以聚合函数的形式展示出来:
select cls, COUNT(*) as num, AVG(UserAge) as avgage
from userInfo
group by cls
-- ↑ 求每个班的人数
-- 每一组的每个具体成员的年龄虽然都被屏蔽了,但我们可以展示这一组的所有成员的平均年龄
-- 这是"行的合并"的思想,好好理解一下
★ 其本质是根据分组依据进行行的合并
▶ 分组之后根据分组的结果再筛选(having)
-- 统计各班级的各性别的学生编号大于15的学生人数
select cId, sGender, COUNT(*)
from StudentInfo
where sId > 15
group by cId, sGender
-- 注意group by分组写在where条件查询之后,弄清这个逻辑:先通过where筛选出所有需要分组的学生,再对这些学生进行分组
-- 统计各班级的各性别的学生编号大于15的学生人数大于3的组的信息(即分组之后根据分组信息再进行一次筛选)
select cId, sGender, COUNT(*)
from StudentInfo
where sId > 15
group by cId, sGender having COUNT(*)>3
▶ 分组的扩展(cube 和 rollup)
group by 后面还可以再加with cube或with rollup,增加多行统计结果集
-- 查询student表,统计各专业男生、女生人数及每个专业学生人数,男生总人数、女生总人数,以及所有学生总人数
select specialty, ssex, grade, count(*)
from student
group by specialty, ssex,grade with cube
--(★重难点)
-- cube用在group by之后,作用为:不仅根据分组依据进行分组统计,再根据分组依据的所有子集(包括空集)进行分组统计
-- demo: 分组依据为 a, b, c,则结果集多了很多行统计结果分组依据分别为(a, b, c)(a, b)(a, c)(a, c)(a)(b)(c)(空)
-- 统计每个专业的男女生人数,每个专业的总人数和所有学生的总人数
select specialty, ssex, count(*)
from student
group by specialty, ssex with rollup
--(★重难点)
-- rollup用在group by之后,作用为:和cube类似,但不是所有子集,而是从最低级别的分组依据开头的子集和空集
-- demo: 分组依据为 a, b, c,则结果集多了很多行统计结果分组依据分别为(a, b, c)(a, b)(a)(空)
▶ select语句的层次关系
select distinct top n * -- 需要查询展示的列
from table1
inner join table2 on ...
inner join table3 on ... -- 构造完整的查询表
where ... -- 先where筛选出数据等待分组或排序
group by ... having ... -- where筛选后再分组;想要根据分组得到的信息再筛选,使用having
order by ... -- 最后对筛选、分组(再筛选)的信息进行排序
> _ <