一、查询数据(查询准备工作)
准备工作:通过sql文件导入数据
首先要熟悉业务。
xsb 学生表
xh 学号 xm姓名 xb性别 jg籍贯 nl年龄 bj班级 sfzh身份证 zcrq注册日期
kcb 课程表
kch课程号 kcm课程名
cjb成绩表
kch课程号 cj成绩 xh学号
二、单表查询
例子1:普通查询
查询 一张表中的所有字段的数据
select * from xsb;
注:* 代表所有的字段,也可以改为某个字段,就是查询部分字段,如下
查询一张表中的部分字段(xm和nl)数据
select xm,nl from xsb;
例子2:条件查询
查询张三的基本信息
select * from xsb where xm='张三';
例子3:逻辑查询 (and or not !=)
查询张三和李四的信息
select * from xsb where xm='张三' or xm='李四';
查询除张三以外的所有人
select * from xsb where xm!='张三' ;
查询18岁的李四
select * from xsb where xm='李四'and nl=18;
例子4:模糊查询
注:%代表一个或多个字符 _代表1个字符(汉字)
查询姓张和姓李的学生信息
select * from xsb where xm like '李%' or xm like '张%';
例子5:集合查询 (关键字 in)
查询来自 北京 上海 山东的学生
select * from xsb where jg in('北京','上海','山东');
例子6:去重查询
查询学生的籍贯
select distinct jg from xsb;
例子7:排序查询
查询学生的信息,按照年龄升序(asc可省)默认升序
select * from xsb order by nl asc;
查询学生的信息,按照年龄降序(desc)
select * from xsb order by nl desc;
只查男生的信息,按年龄升序
select * from xsb where xb='男' order by nl desc;
注意:如果 where 和 order by 同时存在。order by 要在 where 的后面
例子8:空(is null)和非空查询(is not null)
查询有成绩的学生
select xh from cjb where cj is not null;
例子9:分页查询
方式一:limit 开始的条数,显示的条数
方式二:limit 显示的条数 (默认从头开始)
查询学生表 从第2条数据开始 查询4条数据
select * from xsb limit 1,4;
查询前5条数据
select * from xsb limit 5;
例子10:范围查询
查找18~21岁的学生 (用条件查询 where nl>=18 and nl<=21)
select * from xsb where nl between 18 and 21;
例子11:统计查询(统计函数 或 集合函数)
count(*或字段) 统计记录总数
sum( ) 统计和
avg( ) 平均数
max( ) 最大值
min( ) 最小值
例子:查询 年龄 大于 20 岁的学生人数
分析:条件 where 年龄大于20岁
学生人数===》count( )
扩展一个别名( 给查询结果取个名字 用 as '' )查询
select count(*) as '总人数' from xsb where nl>20;
成绩表中总记录数
select count(*) as '总记录数' from cjb;
对成绩求总和
select sum(cj) as '总分' from cjb;
例12:分组查询(难点)看到“每”想到分组(关键字 group by)
小例子1,统计 选修每个课程的总人数
分析:1、考虑操作的表cjb
2、按照哪个分组?===>安装kch分组
一个kch 对应多个学号====》count( )===>总人数
select count(*) as '总人数',kch as'课程号',sum(cj) as '总成绩' from cjb group by kch;
注意(重点):分组查询只能查整体信息,不能查部分信息!!
整体信息指:1.统计函数 2.组名
部分信息指:小组成员的内容
小例子2,查询两门课以上(包含两门)课程不及格的学生学号
思路:
1、确定表===》cjb
2、确定分组字段===》xh
3、确定条件
where =====》分组之前的条件(例子:不及格学生)
having=====》分组之后的条件(例子:两门课程以上)
select xh from cjb where cj<60 GROUp by xh having count(*)>=2 ;
三、多表查询
1、多表查询--------子查询(嵌套查询)
什么是子查询? 将 select 语句作为另一条 select 语句的条件
需求:查询涉及的字段不止一张表,联想子查询
例子1:查询 选修 Java 课程的全部学生的总成绩。
分析:
1、查询总成绩======》cjb
2、选修 Java 课程的学生=====》kcb
3、两张表之间的联系字段(外键)====》kch
模板:查询结果 where 联系字段 in 查询条件
select sum(cj) as '总成绩' from cjb where kch in (select kch from kcb where kcm='java语言');
例子2:实现 1班张三 同学java语言的成绩
1、查询结果===》成绩====》cjb
2、查询条件
2.1 1班+张三====》xsb
2.2 java语言=====》kcb
3、两张表的联系字段(外键)======》xh kch
模板:查询结果 where 联系字段 in 查询条件1 and 查询条件2
select cj as '成绩' from cjb where xh in(select xh from xsb where xm='张三'and bj='1班') and kch in(select kch from kcb where kcm='java语言');
2、多表查询-------关联查询(连接查询)
(1)等值关联查询
需求:要求同时显示多张表中的内容联想 关联查询(表合并查询)
思路:1、表合并
2、过滤有效数据
3、条件
模板:等值过滤查询
select 字段 from 表1,表2…… where 等值过滤 and 其他条件
例子:查询张三各科的考试成绩,要求同时显示姓名、课程号和成绩
注意:遇到重复的字段名 带上表名. 如kcb.kch
select xm,kcb.kch,cj from xsb,cjb,kcb where xsb.xh=cjb.xh AND kcb.kch=cjb.kch AND xm='张三';
(2)左右关联查询
需求:
查询 学生的课程成绩 要求同时显示姓名、课程号和成绩
要求显示全部的学生和成绩(即使成绩不存在 学生信息也能全部显示)
左右关联查询
语法:
左关联:a表 left join b表 on条件 保障左表记录可以全部显示 右关联:a表 right join b表 on条件 保障右表记录可以全部显示
select xm,cj from xsb left join cjb on xsb.xh=cjb.xh ;
(3)自关联(内关联---inner join)
数据准备:
Create table areas(
aid int primary key,
atitle varchar(20),
pid int
);
insert into areas values ('130000', '河北省', NULL),
('130100', '石家庄市', '130000'),
('130400', '邯郸市', '130000'),
('130600', '保定市', '130000'),
('130700', '张家口市', '130000'),
('130800', '承德市', '130000'),
('410000', '河南省', NULL),
('410100', '郑州市', '410000'),
('410300', '洛阳市', '410000'),
('410500', '安阳市', '410000'),
('410700', '新乡市', '410000'),
('410800', '焦作市', '410000');
需求:
查询河北省的所有城市
答案1:只要求显示城市名字(子查询)
分析思路:
查询结果===》select * from areas
查询条件===》 select aid from areas where atitle='河北省';
表联系字段(外键) pid
模板:查询结果 where 联系字段 in 查询条件
select * from areas where pid in (select aid from areas where atitle='河北省');
答案2:要求省份和市同时显示
需求:有些数据经过条件后导致无法显示
解决:自关联------inner join(本质 自己和自己做 笛卡尔积 关联)
注意:自己和自己关联 字段 全部重复 要设置两个别名 如p和c
select * from areas as p inner join areas as c on p.aid=c.pid;