【狂神说Java】--MySQL(四)DQL查询数据(最重点)

首先,请下载用到的数据库文件,下面这篇文章有

跟着狂神学java——MySQL所用到的包

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

Mysqld的7种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表提供了subjectnostudentresult
student表提供了studentno studentnamesubject表提供了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里面,一个淘宝页面能显示出来,经过了很多数据库的查询

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ningmengshuxiawo/article/details/114790086