首先,请下载用到的数据库文件,下面这篇文章有
4.1 DQL
Data Query Language 数据库查询语言 查询是最重要的
1:所有查询操作都用它 Select
2:简单的查询,复杂的查询,它都能做
3:数据库中最核心的语言,最重要的语言
4: 使用频率最高的语言
首先我们创建一个数据库,以及建立学生表、年级表、科目表、成绩表
CREATE DATABASE IF NOT EXISTS `school`;
-- 创建一个school数据库
USE `school`;-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`loginpwd` VARCHAR(20) DEFAULT NULL,
`studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
`sex` TINYINT(1) DEFAULT NULL COMMENT '性别,0或1',
`gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
`phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
`address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
`borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
`email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
`identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
PRIMARY KEY (`studentno`),
UNIQUE KEY `identitycard`(`identitycard`),
KEY `email` (`email`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
-- 创建年级表
DROP TABLE IF EXISTS `grade`;
CREATE TABLE `grade`(
`gradeid` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY (`gradeid`)
) ENGINE=INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8;
-- 创建科目表
DROP TABLE IF EXISTS `subject`;
CREATE TABLE `subject`(
`subjectno`INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
`subjectname` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',
`classhour` INT(4) DEFAULT NULL COMMENT '学时',
`gradeid` INT(4) DEFAULT NULL COMMENT '年级编号',
PRIMARY KEY (`subjectno`)
)ENGINE = INNODB AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8;
-- 创建成绩表
DROP TABLE IF EXISTS `result`;
CREATE TABLE `result`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`subjectno` INT(4) NOT NULL COMMENT '课程编号',
`examdate` DATETIME NOT NULL COMMENT '考试日期',
`studentresult` INT (4) NOT NULL COMMENT '考试成绩',
KEY `subjectno` (`subjectno`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;
-- 插入学生数据 其余自行添加 这里只添加了2行
INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','张伟',0,2,'13800001234','北京朝阳','1980-1-1','[email protected]','123456198001011234'),
(1001,'123456','赵强',1,3,'13800002222','广东深圳','1990-1-1','[email protected]','123456199001011233');
-- 插入成绩数据 这里仅插入了一组,其余自行添加
INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
VALUES
(1000,1,'2013-11-11 16:00:00',85),
(1000,2,'2013-11-12 16:00:00',70),
(1000,3,'2013-11-11 09:00:00',68),
(1000,4,'2013-11-13 16:00:00',98),
(1000,5,'2013-11-14 16:00:00',58);
-- 插入年级数据
INSERT INTO `grade` (`gradeid`,`gradename`) VALUES(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');
-- 插入科目数据
INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);
4.2 指定查询字段
查询表中全部数据
SELECT * FROM `student`
SELECT * FROM `result`
查询表中指定字段
SELECT `studentno`, `studentname` FROM `student`
别名
:给查找出来的结果重新命名,也可以给表取别名
SELECT `studentno` AS 学号 ,`studentname` AS 学生姓名 FROM `student`
拼接字符串
SELECT CONCAT('姓名:',`studentname`) AS 新名字 FROM `student` -- 拼接字符串
去重(去除select语句查询出来的结果中重复的数据)
SELECT *FROM result -- 查询所有成绩
SELECT `studentno` FROM `result` -- 查询成绩表中的学号
SELECT DISTINCT `studentno` FROM result -- 去重
查看mysql版本
SELECT VERSION()
查询计算结果
给查询出来的数据加1
SELECT `studentno`,`studentresult` FROM `result`
SELECT `studentno`,`studentresult`+1 AS 加一分后 FROM `result`
数据库中的表达式:文本值,列,Null,函数,计算表达式,系统变量
4.3 where条件子句
作用:检索数据库中符合条件的值
** AND &&**
SELECT `studentno`,`studentresult` FROM `result` WHERE `studentresult`>=95 AND `studentresult`<=100
模糊查询(区间)
SELECT `studentno`,`studentresult` FROM `result` WHERE `studentresult` BETWEEN 80 AND 100
模糊查询:比较运算符
查询姓刘的同学 用like结合%,%代表0到任意个字符 _代表一个字符
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentname` LIKE '刘%'
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentname` LIKE '刘_'
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentname` LIKE '刘__' -- 查询出姓刘但是名字有三个字的
查询名字中间有‘家’字的同学
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentname` LIKE '%家%'
查询 1001 1002 1003 学员信息
SELECT `studentno` ,`studentname` FROM `student` WHERE `studentno` IN (1001,1002,1003)
查询在北京,重庆的学生
SELECT `studentno` ,`studentname` ,`address` FROM `student` WHERE `address` IN ('北京房山','重庆北碚') -- in 里面必须是具体的一个值或多个值,不能用%这种
查询地址为空的学生
SELECT `studentno` ,`studentname` ,`address` FROM `student` WHERE `address`='' OR `address` IS NULL
SELECT `studentno` ,`studentname`,`borndate` FROM `student` WHERE `borndate` IS NOT NULL
4.4 联表查询 join
Inner join
-- 查询参加了考试的同学的学号,姓名,科目编号,分数,涉及到多张表
/*
思路:1分析查到的字段来自哪几张表,如果有多张表,就要用连接查询
2 确定使用哪种连接查询
确定交叉点(这两个表中那个数据是相同的)
判断条件:学生表中的 `studentno`==成绩表中的`studentno`
因为两张表都有`studentno`,所以需要起别名
INNER JOIN 查交集
*/
SELECT `studentno`, `studentname`, `subjectno`,`studentresult`
FROM `student` AS S
INNER JOIN `result` AS R
WHERE S.`studentno`=R.`studentno`
分析:studentno
指向不明
解决方法 S.studentno
SELECT S.`studentno`, `studentname`, `subjectno`,`studentresult`
FROM `student` AS S
INNER JOIN `result` AS R
WHERE S.`studentno`=R.`studentno`
student
表
result
表
Inner join
结果
交集无疑了
Right join
SELECT S.`studentno`, `studentname`, `subjectno`,`studentresult`
FROM `student` S -- 这里空格与AS一样,都是起别名
RIGHT JOIN `result` R
ON S.`studentno`=R.`studentno`
结果:
Left join
SELECT S.`studentno`, `studentname`, `subjectno`,`studentresult`
FROM `student` S -- 这里空格与AS一样,都是起别名
LEFT JOIN `result` R
ON S.`studentno`=R.`studentno`
join on
:连接查询:join (连接的表) on(判断条件)
where
:等值查询
思考题 查询参加了考试的同学的学号,姓名,科目编号,分数,科目名字 涉及到多张表
分析:我要查询哪些字段,从哪几个表中查找
我要查询哪些数据select …
从哪几个表中查 FROM表XXx Join连接的表 on 交叉条件
假设存在一种多张表查询,慢慢来,先查询两张表然后再慢慢增加
SELECT s.`studentno`,`studentname`,r.`subjectno`,`subjectname`,`studentresult` -- 先确定用到的字段
FROM `student` s -- 先引入`student`表,为了避免字段冲突,起个别名为s
RIGHT JOIN `result` r -- 把`student`表和`result`表进行右连接,得到参加考试的学生的学号,姓名,考试科目编号,考试结果
ON s.`studentno`=r.`studentno` -- 这是连接判断条件,右连接,就是取出`result`表中所有数据,再拼接 `student`表中的名字
INNER JOIN `subject` sub -- 上面去的的结果与`subject` 做内连接,取得`subjectno`
ON r.`subjectno`=sub.`subjectno` -- 内连接条件
查询结果
下图是 result
原表,可以看出上表中, result
表提供了subjectno
,studentresult
student
表提供了studentno
studentname
,subject
表提供了studentresult
总结:
Inner join相当于取交集
left join
以左表为基准,比如下面的代码,根被就不会判断两个表的studentno
是不是相等,而是会取出S表中所有的studentno
所在的行,只是为了拼接R中存在的字段
LEFT JOIN `result` R
ON S.`studentno`=R.`studentno`
right join
以右表为基准,比如下面的代码,根被就不会判断两个表的studentno
是不是相等,而是会取出R表中所有的studentno
所在的行,只是为了拼接S表中存在的字段
RIGHT JOIN `result` R
ON S.`studentno`=R.`studentno`
自连接(自己跟自己连接)(了解即可)
核心:一张表拆成两张一样的表即可
先建一个表
CREATE TABLE `school`.`category`( `categoryid` INT(3) NOT NULL COMMENT 'id', `pid` INT(3)
NOT NULL COMMENT '父id 没有父则为1', `categoryname` VARCHAR(10) NOT NULL COMMENT '种类名字
', PRIMARY KEY (`categoryid`) ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('2', '1', '信息技术');
insert into `school`.`CATEGOrY` (`categoryid`, `pid`, `categoryname`) values ('3', '1', '软件开发');
insert into `school`.`category` (`categoryid`, `PId`, `categoryname`) values ('5', '1', '美术设计');
insert iNTO `School`.`category` (`categoryid`, `pid`, `categorynamE`) VAlUES ('4', '3', '数据库');
insert into `school`.`category` (`CATEgoryid`, `pid`, `categoryname`) values ('8', '2', '办公信息');
insert into `school`.`category` (`categoryid`, `pid`, `CAtegoryname`) values ('6', '3', 'web开发');
inserT INTO `SCHool`.`category` (`categoryid`, `pid`, `categoryname`) valueS ('7', '5', 'ps技术');
SELECT a.`categoryname` AS '父栏目', b.`categoryname` AS '子栏目'
FROM `category` AS a,`category` AS b
WHERE a.`categoryid`=b.`pid`
查询学生所属的年级(学号,姓名,年级)
SELECT `studentno`,`studentname`,`gradename`
FROM student s
INNER JOIN `grade` g
ON s.`gradeid`=g.`gradeid`
查询科目所属的年级
SELECT `subjectname`,s.`gradeid`
FROM `subject` s
INNER JOIN `grade` g
ON s.`gradeid`=g.`gradeid`
查询参加了高等数学-1 考试的同学信息:学号,学生姓名,科目名,分数
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
INNER JOIN `result` r
ON s.`studentno`=r.`studentno`
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE `subjectname`='高等数学-1'
4.5 分页和排序
分页关键词:limit
排序关键词:order by 语法格式: order by 字段
ASC
排序:升序 (ASC) 降序(DSC)
为什么要分页?
缓解数据库压力,给人的体验更好
查询 高等数学-1课程成绩排名前10的学生,并且分数要大于80的学生信息(学号,姓名,课程名称,分数)
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` s
INNER JOIN `result` r
ON s.`studentno`=r.`studentno`
INNER JOIN `subject` sub
ON sub.`subjectno`=r.`subjectno`
WHERE `subjectname`='高等数学-1' AND `studentresult` >=80
ORDER BY `studentresult` DESC -- 按照`studentresult`降序排列
LIMIT 0,10 -- 分页,每页10条,显示第一页
4.6 子查询
子查询类似于嵌套select语句
4.7 分组和过滤
查询不同课程的平均分,最高分,最低分
核心:根据不同的课程分组
SELECT `subjectname` AS 课程名称 ,AVG(`studentresult`)AS 平均分 ,MAX(`studentresult`)AS 最高分 ,MIN(`studentresult`)AS 最低分 -- as 课程编号, 平均分,最高分,最低分
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno` -- 不分组只能查出来一条记录是因为最高最低只有一个
分组过滤
SELECT `subjectname` AS 课程名称 ,AVG(`studentresult`)AS 平均分 ,MAX(`studentresult`)AS 最高分 ,MIN(`studentresult`)AS 最低分 -- as 课程编号, 平均分,最高分,最低分
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno` -- 不分组只能查出来一条记录是因为最高最低只有一个
GROUP BY r.`subjectno` -- 通过某一字段分组
挑选平均分大于80分的数据
我的第一想法
WHERE AVG(`studentresult`)>80
SELECT `subjectname` AS 课程名称 ,AVG(`studentresult`)AS 平均分 ,MAX(`studentresult`)AS 最高分 ,MIN(`studentresult`)AS 最低分 -- as 课程编号, 平均分,最高分,最低分
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno` -- 不分组只能查出来一条记录是因为最高最低只有一个
WHERE AVG(`studentresult`)>80
GROUP BY r.`subjectno` -- 通过某一字段分组
having —过滤分组的记录必须满足的次要条件
而且having在group by 的下面
对函数进行过滤用having ,where不能和group by 连用
where是判断每一条记录,having二次过滤可以判断组
SELECT `subjectname` AS 课程名称 ,AVG(`studentresult`)AS 平均分 ,MAX(`studentresult`)AS 最高分 ,MIN(`studentresult`)AS 最低分 -- as 课程编号, 平均分,最高分,最低分
FROM `result` r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno` -- 不分组只能查出来一条记录是因为最高最低只有一个
GROUP BY r.`subjectno` -- 通过某一字段分组
HAVING AVG(`studentresult`)>80
select小结
查询注意事项
有时候查询不见会跨表查询,还可能跨数据库查询,有可能是oracle,mongDB,Redis等等,这些层面是用Java写的
比如一个淘宝页面,淘宝号称千人千面,每个人进去的页面展现都是不同的,但是都有商品视频、图片、价格、评论这些,这些东西都是从不同的数据库里面查出来的。价格,标题,数量这些可以放在mysql,图片是非关系的,可能放在mongDB,视频可能放在一个专门的文件存储系统(hdfs或者fasthdfs,包括阿里云的os),评论是一些热点数据,可能是放在redis里面,一个淘宝页面能显示出来,经过了很多数据库的查询