DQL :数据查询语言,用于检索数据库中的数据,主要是SELECT语句;
导入sql:
-- 创建 school数据库
CREATE DATABASE IF NOT EXISTS `school`;
USE school;
-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
`StudentNo` INT(4) NOT NULL COMMENT ‘学号‘,
`LoginPwd` VARCHAR(20) DEFAULT NULL COMMENT ‘登录密码‘,
`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) DEFAULT NULL COMMENT ‘家庭住址‘,
`BornDate` DATE 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;
-- 添加学生数据
INSERT INTO `student`(`StudentNo`,`StudentName`,`LoginPwd`,`Sex`,`GradeID`,`Phone`,`Address`,`BornDate`,`Email`,`IdentityCard`)
VALUES
(1001,‘赵虎‘,‘123456‘,0,2,‘13713766677‘,‘湖北武汉‘,‘2008-08-17‘,‘123456@qq.com‘,‘420101200808171233‘),
(1002,‘张小猛‘,‘123456‘,1,1,‘13913766677‘,‘湖南长沙‘,‘2007-06-17‘,‘523456@qq.com‘,‘430100200706171244‘),
(1003,‘李萌‘,‘123456‘,1,3,‘13813766677‘,‘浙江杭州‘,‘2008-05-20‘,‘723456@qq.com‘,‘330100200805201266‘),
(1004,‘林冲‘,‘123456‘,0,2,‘15013766677‘,‘四川成都‘,‘2009-06-17‘,‘523456@qq.com‘,‘ 510101200906171255‘);
-- 创建年级表
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;
-- 添加年级数据
INSERT INTO `grade`(`GradeID`,`GradeName`) VALUES(1,‘大一‘),(2,‘大二‘),(3,‘大三‘),(4,‘大四‘);
-- 创建科目表
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;
-- 添加科目数据
INSERT INTO `subject`(`SubjectNo`,`SubjectName`,`ClassHour`,`GradeId`)
VALUES
(1,‘高等数学-1‘,100,1),
(2,‘高等数学-2‘,100,2),
(3,‘高等数学-3‘,100,3),
(4,‘高等数学-4‘,100,4),
(5,‘Java程序设计-1‘,120,1),
(6,‘Java程序设计-2‘,120,2),
(7,‘Java程序设计-3‘,120,3),
(8,‘Java程序设计-4‘,120,4),
(9,‘数据结构-1‘,119,1),
(10,‘数据结构-2‘,119,2),
(11,‘数据结构-3‘,119,3),
(12,‘数据结构-4‘,119,4),
(13,‘C#.NET‘,90,1);
-- 创建成绩表
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;
-- 添加成绩数据
INSERT INTO `result`(`StudentNo`,`SubjectNo`,`ExamDate`,`StudentResult`)
VALUES
(1001,2,‘2020-7-3‘,90),
(1002,1,‘2020-7-3‘,72),
(1003,3,‘2020-7-3‘,61),
(1004,2,‘2020-7-3‘,59),
(1001,6,‘2020-7-3‘,73),
(1002,5,‘2020-7-3‘,66),
(1003,7,‘2020-7-3‘,55),
(1004,6,‘2020-7-3‘,88),
(1001,10,‘2020-7-4‘,90),
(1002,9,‘2020-7-4‘,72),
(1004,10,‘2020-7-4‘,66),
(1002,13,‘2020-7-4‘,90);
1、SELECT语句基本语法
语法格式如下:
-- 查询表中全部的数据
SELECT * FROM 表名 [WHERE条件];
-- 按照指定列查询
SELECT 字段1,字段2,字段3 [WHERE条件];
2、AS 关键字(别名)
-
有的时候,列名不是那么见名知意,所以呢我们就可以给它啦。
-
可以给字段起别名,也可以给表起别名。
-
表别名只在执行查询时使用,并不在返回结果中显示。
-
而列定义别名之后,将返回给客户端显示,显示的结果字段为字段列的别名(即字段别名就是表头)。
语法格式如下:
SELECT 字段名 AS 字段的别名 FROM 表名 AS 表的别名;
【示例】别名的使用
SELECT `StudentNo` AS 学号,`StudentName` AS 学生姓名 FROM student AS stu;
3、CONCAT(a,b)函数
CONCAT(a,b)函数:用于拼接字符串。
【示例】CONCAT函数的使用
SELECT CONCAT(‘姓名:‘,`StudentName`)AS 新名字 FROM student;
4、DISTINCT (去重)
作用:去除SELECT查询出来的结果中重复的数据,重复的数据只显示一条。
【示例】使用去重查看参加考试的同学
SELECT DISTINCT `StudentNo` FROM result;
5、数据库的列 (表达式)
SELECT VERSION(); -- 查询系统版本 (函数)
SELECT 4*2*3.14 AS 计算结果; -- 用于计算 (表达式)
SELECT @@auto_increment_increment; -- 查询自增的步长(变量)
-- 学生考试成绩+10分查看
SELECT `StudentNo` AS 学号,`SubjectNo` AS 课程编号,`StudentResult`+10 AS `成绩(+10)` FROM result;
数据库中的表达式:文本值,列,Null,函数,计算表达式,系统变量...
6、where条件语句
作用:用于检索数据中符合条件的值。结果为布尔值!
搜索的条件由一个表达式或者多个组成
运算符 | 语法 | 描述 |
---|---|---|
and && | a and b a&&b | 逻辑与,两个都为真,则结果为真。 |
or || | a or b a||b | 逻辑或,其中有一个结果为真,则结果为真。 |
not ! | not a !a | 逻辑非,真为假,假为真。 |
【示例】运算符的使用
-- 查询分数在80-100之间的
SELECT StudentNo,`StudentResult` FROM result WHERE StudentResult>=80 AND StudentResult<=100;
-- 模糊查询(区间)
SELECT StudentNo,`StudentResult` FROM result WHERE StudentResult BETWEEN 88 AND 100;
-- 查询所有同学的信息,不包含学号为1001的同学
SELECT StudentNo,`StudentResult` FROM result WHERE StudentNO!=1001;
SELECT StudentNo,`StudentResult` FROM result WHERE NOT StudentNO=1001;
7、模糊查询 (比较运算符)
运算符 | 语法 | 描述 |
---|---|---|
IS NULL | a is null | 如果操作符为null,则结果为真 |
IS NOT NULL | a is not null | 如果操作符不为null,则结果为真 |
BETWEEN | a between b and c | 若a在b和c之间,则结果为真 |
Like | a like b | SQL匹配,如果a能匹配到b,则结果为真 |
In | a in (a1,a2,a3,...) | 假设a在 a1,或者a2...其中的某一个值中,则结果为真 |
【示例】Like,查询姓刘的同学
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentName LIKE ‘刘%‘;
【示例】Like,查询姓刘的同学,名字后面只有一个字的
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentName LIKE ‘刘_‘;
【示例】Like,查询姓刘的同学,名字后面只有两个字的
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentName LIKE ‘刘__‘;
【示例】Like,查询名字中有富字的同学
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentName LIKE ‘%富%‘;
【示例】In,查询1001,1002,1003号学员
SELECT `StudentNo`,`StudentName` FROM `student` WHERE StudentNo IN(1001,1002,1003);
【示例】IS NULL,查询地址为空的学生(null或者‘’)
SELECT `StudentNo`,`StudentName` FROM `student` WHERE Address=‘‘ OR Address IS NULL;
【示例】IS NOT NULL,查询设置出生日期的同学(出生日期不为空)
SELECT `StudentNo`,`StudentName` FROM `student` WHERE BornDate IS NOT NULL;
8、联表查询
join的七种用法:left join(左连接)、right join(右连接) 、inner join(内连接)、outer join(外连接)。
INNER JOIN (内连接)
内连接:两张表之间的交集,内连接用on或者where进行关联都是可以的。
【示例】使用内连接,查询学号,姓名,课程编号,考试成绩
- 分析:因为姓名不在成绩表中,然后两个表中有相同的列(学号),所以我们使用内连接(inner join);
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student AS s INNER JOIN result AS r
WHERE s.StudentNo = r.StudentNo;
RIGHT JOIN (右外连接)
右连接 :以右表为标准 ,到左表寻找匹配的数据。
【示例】使用右连接,查询学号,姓名,课程编号,考试成绩
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student s
RIGHT JOIN result r
ON s.StudentNo=r.StudentNo;
LEFT JOIN (左外连接)
左连接 :以左表为标准,到右表寻找匹配的数据。
【示例】使用左连接,查询学号,姓名,课程编号,考试成绩(会发现没有考试的同学也会显示出来)
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student s
LEFT JOIN result r
ON s.StudentNo=r.StudentNo;
【示例】使用左连接,查询缺考的同学
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student s
LEFT JOIN result r
ON s.StudentNo=r.StudentNo
WHERE r.SubjectNo IS NULL;
【示例】 查询参加考试的同学信息(学号,姓名,科目名称,考试成绩)
-- 思路:先查询两张表然后在慢慢增加另一张表(也是找关联的列)
SELECT s.StudentNo,StudentName,SubjectName,StudentResult
FROM student s
RIGHT JOIN result r
ON r.StudentNo = s.StudentNo
INNER JOIN `subject` sub
ON r.SubjectNo=sub.SubjectNo
WHERE StudentResult IS NOT NULL;
【示例】查询学员所属的年级(学号,姓名,年级名称)
-- 使用内连接查询
SELECT StudentNo,StudentName,GradeName
FROM student s
INNER JOIN grade g
ON s.`GradeID`=g.`GradeID`;
-- 使用左外连接查询
SELECT StudentNo,StudentName,GradeName
FROM student s
LEFT JOIN grade g
ON s.`GradeID`=g.`GradeID`;
【示例】查询科目所属的年级(科目名称,年级名称)
SELECT `SubjectName`,`GradeName`
FROM `subject` sub
INNER JOIN grade g
ON
sub.`GradeId`=g.`GradeID`;
【示例】查询参加数据列举考试的同学信息(学号,学生姓名,科目名称,分数)
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 sub.`SubjectName` = ‘数据结构-1‘
总结:
操作 | 描述 |
---|---|
inner join | 如果表中至少有一个匹配,就返回行 |
left join | 会从左表中返回所有的值,即使右表中没有匹配 |
right join | 会从右表中返回所有的值,即使左表中没有匹配 |
9、自连接(了解)
自连接是join的一种用法,但并不是连接的一种类型,因为他的本质是把一张表当成两张表来使用。
-- 创建分类表
CREATE TABLE `category`(
`categoryid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT ‘主题id‘, -- UNSIGNED不含符号
`pid` INT(10) NOT NULL COMMENT ‘父id‘,
`categoryname` VARCHAR(10) NOT NULL COMMENT ‘主题名称‘,
PRIMARY KEY (`categoryid`)
) ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ;
-- 向分类表插入数据
INSERT INTO `category` (`categoryid`, `pid`, `categoryname`) VALUES (2, 1, ‘信息技术‘);
INSERT INTO `category` (`categoryid`, `pid`, `categoryname`) VALUES (3, 1, ‘软件开发‘);
INSERT INTO `category` (`categoryid`, `PId`, `categoryname`) VALUES (5, 1, ‘美术设计‘);
INSERT INTO `category` (`categoryid`, `pid`, `categorynamE`) VALUES (4, 3, ‘数据库‘);
INSERT INTO `category` (`CATEgoryid`, `pid`, `categoryname`) VALUES (8, 2, ‘办公信息‘);
INSERT INTO `category` (`categoryid`, `pid`, `CAtegoryname`) VALUES (6, 3, ‘web开发‘);
INSERT INTO `category` (`categoryid`, `pid`, `categoryname`) VALUES (7, 5, ‘ps技术‘);
父类:
categoryid | categoryname |
---|---|
2 | 信息技术 |
3 | 软件开发 |
5 | 美术技术 |
子类:
pid | categoryid | categoryname |
---|---|---|
3 | 4 | 数据库 |
3 | 6 | web开发 |
5 | 7 | ps技术 |
2 | 8 | 办公信息 |
操作:父类对应的子类关系;
父类 | 子类 |
---|---|
信息技术 | 办公信息 |
软件开发 | 数据库 |
软件开发 | web开发 |
美术技术 | ps技术 |
-- 查询父子信息
SELECT a.categoryname AS ‘父栏目‘,b.categoryname AS ‘子栏目‘
FROM `category` AS a,`category` AS b
WHERE a.`categoryid`=b.`pid`;