环境说明:
数据库:Mysql 5.5
连接软件:Navicat
前言
SQL总结系列目录:
- SQL系列总结(一):DDL(数据定义语言)- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com)
- SQL系列总结(二):DQL(数据查询语言)- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com)
- SQL系列总结(三):DML(数据操纵语言) - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com)
- SQL系列总结(四):DCL(数据控制语言) - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com)
- SQL系列总结(五):TCL(事务控制语言) - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com)
数据查询是数据库的核心操作。因此,数据查询语言DQL(Data Query Language)是SQL中的核心部分,它允许用户查询数据,这也是通常最频繁的数据库日常操作。
SQL提供了SELECT
进行语句查询,该语句具有灵活的使用方式和丰富的功能。SELECT
语句既可以完成简单的单表查询,也可以完成复杂的连接查询和嵌套查询。
准备数据
本篇博客中出现的SQL语句实例基于下面的三张数据表:
{tabs-pane label="学生表"}
Student(Sno,Sname,Ssex,Sage,Sdept)
代码语言:javascript复制-- 创建表:
CREATE TABLE Student(Sno CHAR(6) Primary KEY, -- 学号 主键
Sname VARCHAR(20), -- 名字
Ssex CHAR(2), -- 性别
Sage INT, -- 年龄
Sdept VARCHAR(20) -- 系部
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入数据:
INSERT INTO Student VALUES('202101','李勇','男',20,'计算机系');
INSERT INTO Student VALUES('202102','刘晨','女',19,'计算机系');
INSERT INTO Student VALUES('202103','王敏','女',18,'数学系');
INSERT INTO Student VALUES('202104','张立','男',18,'信息系');
{/tabs-pane}
{tabs-pane label="课程表"}
Course(Cno,Cname,Cpno,Ccredit)
代码语言:javascript复制-- 创建表:
CREATE TABLE Course(Cno CHAR(1) PRIMARY KEY, -- 课程号 主键
Cname VARCHAR(20), -- 课程名
Cpno CHAR(1), -- 前置学科课程号
Ccredit INT -- 学分
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入数据:
INSERT INTO Course VALUES('1','数据库','5',4);
INSERT INTO Course VALUES('2','数学','null',2);
INSERT INTO Course VALUES('3','信息系统','1',4);
INSERT INTO Course VALUES('4','操作系统','6',3);
INSERT INTO Course VALUES('5','数据结构','7',4);
INSERT INTO Course VALUES('6','数据处理','',2);
INSERT INTO Course VALUES('7','C语言','6',4);
{/tabs-pane}
{tabs-pane label="学生选课表"}
SC(Sno,Cno,Grade)
代码语言:javascript复制-- 创建表:
CREATE TABLE SC(Sno CHAR(6), -- 学号 主键
Cno CHAR(1), -- 课程号 主键
Grade INT, -- 成绩
PRIMARY key(Sno,Cno) -- 设置表级约束条件
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入数据:
INSERT INTO SC VALUES('202101','1',92);
INSERT INTO SC VALUES('202101','2',85);
INSERT INTO SC VALUES('202101','3',88);
INSERT INTO SC VALUES('202102','2',90);
INSERT INTO SC VALUES('202102','3',80);
{/tabs-pane}
0x01.单表查询
单表查询是指仅涉及一个表的查询。是DQL的基础部分。
1.基本查询
基本表的查询很简单,查询指定表的所有数据:
代码语言:javascript复制SELECT * FROM <表名>;
-- 查询结果是一个二维表格
例:查询全体学生的详细信息 SELECT * FROM Student;
也可以查询指定列:
代码语言:javascript复制SELECT <列名1>,<列名2>··· FROM <表名>;
例:查询全体学生的学号姓名信息 SELECT Sno,Sname FROM Student; 有时候查询出来的列会有重复值,可以用
DISTINCT
来消除它们: SELECT DISTINCT Sno,Sname FROM Student;
或者在查询中加入计算表达式。
例:查询全体学生的姓名、出生时间信息 SELECT Sname,2021-Sage FROM Student;
SELECT
语句也可以去掉FROM子句
,如:
SELECT 1;
# 返回结果1
SELECT 1 1;
# 返回结果2
这种只有表达式却没有FROM
子句的SELECT
语句会直接计算出表达式的结果并返回一个列名为表达式、值为计算结果的1*1表格。可以用来判断当前连接与数据库的连接是否有效。
2.条件查询
大部分查询数据中,我们只是需要部分数据,而不是全部数据。因此就需要加上一些条件来筛选掉不需要的数据,可以通过WHERE`关键字后加入相应的查询条件来实现。
WHERE子句常用到的查询条件如下:
查询条件 | 谓词 |
---|---|
比较 | =、>、<、>=、<=、!=、<>、!>、!< |
确定范围 | BETWEEN ... AND... 、NOT BETWEEN ... AND ... |
确定集合 | IN、NOT IN |
字符匹配 | LIKE、NOT LIKE |
判断是否为空 | IS NULL、IS NOT NULL |
多重条件/逻辑运算 | AND、OR、NOT |
比较大小
例1:查询李勇同学的详细信息 SELECT * FROM Student WHERE Sname='李勇'; 例2:查询考试成绩不及格的学生的学号 SELECT Sno FROM SC WHERE Grade<60; 例3:查询所有年龄在20岁以下的学生姓名及其年龄 SELECT Sname,Sage FROM WHERE Sage<20;
确定范围
BETWEEN···AND···
和NOT BETWEEN···AND···
可以用来查找属性值在(或不在)指定范围的元组,其中BETWEEN后是范围的下限(即低值),AND后是范围的上限(即高值)。
例:查询年龄在18~23岁的学生的学号、姓名 SELECT Sno,Sname FROM Student WHERE Sage BEWEEN 18 AND 23;
确定集合
谓词IN
可以用来查找属性值属于指定集合的元组。
例:查询计算机系全体学生的名单 SELECT Sname FROM Student WHERE Sdept IN ('计算机系');
字符匹配
谓词LIKE
可以用来进行字符串的匹配。其一般语法格式如下:
[NOT] LIKE '<匹配串>' [ESCAPE '<换码字符>']
<匹配串>
可以是一个完整的字符串,也可以含有通配符%和
_`。字符匹配规则如下:
%(百分号)代表任意长度的字符串。
例如a%b表示以a开头,以b结尾的任意长度的字符串,如abc、abdewc、ab等都满足该匹配串
_(下划线)代表任意单个字符
例如a_b表示以a开头,以b结尾的长度为3的任意字符串。如abc、afb等都满足该匹配串。
例1:查询所有姓“刘”的学生的学号、姓名和性别 SELECT Sname,Sno,Ssex FROM Student WHERE Sname LIKE '刘%'; 例2:查询姓“欧阳”且全名为三个字的学生的姓名和学号 SELECT Sname,Sno from Student WHERE Sname LIKE='欧阳_'; 例3:查询所有不姓“王”的学生的姓名、学号和性别 SELECT Sname,Sno,Ssex WHERE Sname NOT LIKE '王%';
若用户要查询的字符串本身就含有通配符%
或者_
,这时就要使用ESCAPE ‘<换码字符>’
短语对通配符进行转义了。
例1:查询DB_Design这门课程的课程号和学分 SELECT Cno,Ccredit FROM Course WHERE Cname='DBDesigner' ESCAPE ''; 例2:查询以“DB_”开头,且倒数第三个字符为i的课程的详细情况 SELECT * FROM Course WHERE Cname='DB%i__' ESCAPE '';
判断是否为空
IS NULL
与IS NOT NULL
用来判断条件是否为空
例:查询成绩表中只有选课记录却没有成绩的学生的学号和课程号 SELECT Sno,Cno FROM SC WHERE Grade IS NULL;
多重条件
逻辑运算符AND
和OR
可用来连接多个查询条件。其中AND的优先级高于OR,但可以通添加括号来改变优先级。
例:查询计算机系年龄在20岁以下的学生姓名 SELECT Sname FROM Student WHERE Sage<20;
3.分页查询
在进行表的查询时,若一次查询出来的数据数量很多的话,放在一个页面显示的话数据量太大,不如分页显示,每次显示n条,这就是分页查询。
要实现分页功能,实际上就是从结果集中显示第1~n条记录作为第1页,显示第n 1~2n条记录作为第2页,依次类推。
因此,分页实际上就是从结果集中“截取”出第M~N条记录。这个查询可以通过LIMIT OFFSET
子句实现。
SELECT * FROM <表名> LIMIT OFFSET ;
例:在学生表中查询第二页学生数据,每一页三项数据 SELECT * FROM Student LIMIT 4 OFFSET 6;
0x02.连接查询 ——待完成
0x03.嵌套查询 ——待完成
0x04.集合查询 ——待完成
0x05.基于派生表的查询 ——待完成
主要参考资料:《数据库系统概论(第5版)》 王珊 萨师煊 编著