SQL系列总结(二):DQL(数据查询语言)

2023-07-01 15:51:53 浏览数 (2)

环境说明:

数据库: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子句,如:

代码语言:javascript复制
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可以用来进行字符串的匹配。其一般语法格式如下:

代码语言:javascript复制
[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 NULLIS NOT NULL用来判断条件是否为空

例:查询成绩表中只有选课记录却没有成绩的学生的学号和课程号 SELECT Sno,Cno FROM SC WHERE Grade IS NULL;

多重条件

逻辑运算符ANDOR可用来连接多个查询条件。其中AND的优先级高于OR,但可以通添加括号来改变优先级。

例:查询计算机系年龄在20岁以下的学生姓名 SELECT Sname FROM Student WHERE Sage<20;

3.分页查询

在进行表的查询时,若一次查询出来的数据数量很多的话,放在一个页面显示的话数据量太大,不如分页显示,每次显示n条,这就是分页查询

要实现分页功能,实际上就是从结果集中显示第1~n条记录作为第1页,显示第n 1~2n条记录作为第2页,依次类推。

因此,分页实际上就是从结果集中“截取”出第M~N条记录。这个查询可以通过LIMIT OFFSET 子句实现。

代码语言:javascript复制
SELECT * FROM <表名> LIMIT  OFFSET ;

例:在学生表中查询第二页学生数据,每一页三项数据 SELECT * FROM Student LIMIT 4 OFFSET 6;

0x02.连接查询 ——待完成

0x03.嵌套查询 ——待完成

0x04.集合查询 ——待完成

0x05.基于派生表的查询 ——待完成

主要参考资料:《数据库系统概论(第5版)》 王珊 萨师煊 编著

0 人点赞