Microsoft Word - 第4章 单表查询—样章.doc

Similar documents
Microsoft Word - 第4章 单表查询—教学设计.doc

单元四数据的查询 数据库原理与应用 课内例题 任务 5 多表查询 课内例题 例创建数据表 orders, 并向表中添加记录 首先创建表 orders,sql 语句如下 : CREATE TABLE orders( o_num int NOT NULL AUTO_INCREMENT, o_date d

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

PowerPoint Presentation

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

设计模式 Design Patterns

PowerPoint Presentation

目錄 C ontents Chapter MTA Chapter Chapter

untitled

DB2 (join) SQL DB2 11 SQL DB2 SQL 9.1 DB2 DB2 ( ) SQL ( ) DB2 SQL DB2 DB2 SQL DB2 DB2 SQL DB2 ( DB2 ) DB2 DB2 DB2 SQL DB2 (1) SQL (2) S

四川省普通高等学校

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM

通过Hive将数据写入到ElasticSearch

《C语言程序设计》教材习题参考答案

目錄

1-1 database columnrow record field 不 DBMS Access Paradox SQL Server Linux MySQL Oracle IBM Informix IBM DB2 Sybase 1-2

《C语言程序设计》第2版教材习题参考答案

untitled

PowerPoint Presentation

學 科 100% ( 為 單 複 選 題, 每 題 2.5 分, 共 100 分 ) 1. 請 參 閱 附 圖 作 答 : (A) 選 項 A (B) 選 項 B (C) 選 項 C (D) 選 項 D Ans:D 2. 下 列 對 於 資 料 庫 正 規 化 (Normalization) 的 敘

第四章 关系数据库标准语言SQL.doc

2006年暑期工作安排

幻灯片 1

ebook46-23

作业参考答案

untitled

Guava学习之Resources

untitled

未命名

赵松涛写作

Oracle数据库应用技术13 [兼容模式]

chap07.key

ChinaBI企业会员服务- BI企业

未命名

SQL Server 数据库 SQL 结构化查询语言 是本课程的重点, 要在熟悉语句的语法框架的前提下, 灵活地写出实现实际需求的 SQL 语句 本章的每个例子, 都要在附录 Student 数据库上加以上机练习与变换

设计模式 Design Patterns

untitled

精 品 库 我 们 的 都 是 精 品 _www.jingpinwenku.com (8) 数 据 库 数 据 库 系 统 和 数 据 库 管 理 系 统 之 问 的 关 系 是 ( ) A) 数 据 库 包 括 数 据 库 系 统 和 数 据 库 管 理 系 统 B) 数 据 库 系 统 包 括

Microsoft Word 年9月二级VF真卷.doc

Oracle高级复制冲突解决机制的研究

Microsoft PowerPoint - 05-SQL3-advanced.ppt

SQL: Interactive Queries (2)

《计算概论》课程 第十九讲 C 程序设计语言应用

威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 號 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

上海市本科教学质量年度报告

习题1

Microsoft Word - oracle-排版文件.doc

幻灯片 1


Microsoft Word - MySQL-排版文件.doc

Microsoft Word - 第3章.doc

Untitled

关于正则表达式

untitled

项目 3 创建和管理表 任务实现 Office Visio PK 3 FK FK1 3.1 相关知识 SQL Server 一 制订表规划 1. 表要存储什么对象 2. 表中每一列的数据类型和长度 059

44 Access 2010 数据库程序设计实验教程 图 3 2 简单查询向导二 2. 使用查询向导创建查询 ts2, 查询 tstud 表的 学号 姓名 字段, tcourse 表的 课程名 字段, tscore 表的 成绩 字段 打开 学生管理.accdb, 使用查询向导创建一个查询, 在 简单

3 Driver do Microsoft Access (*.mdb) hisdata IFIX 1.4

课程名称:数据库系统概论

Microsoft Word - 正文.doc

第13章 SQL Server提供的应用程序接口

学生表 主键 : 学号 字段名称 数据字段必填允许空有效性规则类型大小字段字符串 学号 文本 10 是 否 姓名 文本 4 是 否 性别 文本 1 男 Or 女 是 否 籍贯 文本 10 出生日期 日期 / 时间 入学总分 数字 整型 >=0 And <=900 住校否 是 / 否 爱好特长 文本

CC213

Microsoft Word - ch09.doc

幻灯片 1

學 習 目 標 1. 了 解 有 計 畫 的 運 動 之 前, 實 施 身 體 檢 查 的 重 要 性 2. 了 解 熱 身 與 緩 和 運 動 可 以 預 防 運 動 傷 害 3. 了 解 包 紮 護 具 裝 備 與 場 地 器 材 的 維 護, 可 以 避 免 傷 害 發 生 4. 了 解 食

Mx* Language Reference Manual 2016 年 4 月 7 日 1 用词说明 未定义 指中央还没有表态指语言定义中不涉及的部分, 编译器和运行时环境如何表现是未知的 主要是为了给学生实现语言留下足够的空间, 标准测试集里不会出现涉及未定义部分的内容 例如 : 术语 : 源程

Microsoft PowerPoint - 03.Fortran程序设计基础1

123

Microsoft Word - 序+目錄.doc

Apache Spark 2.4 新增内置函数和高阶函数使用介绍

Microsoft Word - 第五讲 SQL.DOC

回滚段探究

ebook45-5

Microsoft Word - 2AF63內文.doc

团 学 要 闻 我 校 召 开 共 青 团 五 届 九 次 全 委 ( 扩 大 ) 会 议 3 月 17 日, 我 校 共 青 团 五 届 九 次 全 委 ( 扩 大 ) 会 议 在 行 政 办 公 楼 五 楼 会 议 室 举 行, 校 团 委 委 员 各 院 ( 系 ) 团 委 书 记 校 学 生

关于“查询设计器”布局 (ADP)

幻灯片 1

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63>

一 個 SQL Injection 實 例 的 啟 示 頁 2 / 6 因 此, 在 知 名 網 站 上 看 到 SQL Injection, 讓 人 驚 心, 卻 不 意 外 網 站 專 案 外 包 是 目 前 業 界 的 常 態, 而 在 價 格 取 勝 的 制 度 下, 低 價 得 標 的 S

SP_ SP_03 JAVA...6 SP_10 SQL...8 SP_ SP_ SP_ SP_ SP_ SP_ SP_ SP_04.NET...33 SP_02 C...37 SP_05

6寸PDF生成工具

PowerPoint 演示文稿

第 一 节 认 识 自 我 的 意 义 一 个 人 只 有 认 识 自 我, 才 能 够 正 确 地 认 识 到 自 己 的 优 劣 势, 找 出 自 己 的 职 业 亮 点, 为 自 己 的 顺 利 求 职 推 波 助 澜 ; 一 个 人 只 有 认 识 自 我, 才 能 在 求 职 中 保 持

目录 1 本期内容 系统管理 连接 MySQL 修改新密码 增加新用户 启动停止 MySQL 数据库操作 库操作 表操作... 5

种 印 证 方 式 正 是 体 现 了 鬼 搭 车 这 个 故 事 的 传 统 性, 如 无 论 古 今 中 外 的 异 文 都 有 冥 钞 这 一 细 节, 因 为 在 外 型 上, 人 们 难 以 把 人 与 鬼 区 别 开 来, 只 能 通 过 冥 钞 鉴 别 人 与 鬼 的 身 份 第 二,

她 摸 了 摸 自 己 的 耳 朵, 看 着 自 己 戴 着 耳 钉 的 耳 朵, 心 中 不 免 有 些 自 豪, 挨 了 三 枪, 在 左 边 打 了 三 个 洞, 不 料 太 疼, 忍 不 下 去, 右 边 的 就 没 有 打 不 过, 还 挺 好 的, 对 称 什 么 的 最 讨 厌 了,

建 立 数 据 库 档 案 用 sqlite3 建 立 数 据 库 的 方 法 很 简 单, 只 要 在 shell 下 键 入 ( 以 下 $ 符 号 为 shell 提 示 号, 请 勿 键 入 ): $ sqlite3 foo.db 如 果 目 录 下 没 有 foo.db,sqlite3 就

第1套

第3节 VHDL语言的常用语法

一步一步教你搞网站同步镜像!|动易Cms

数 据 库 系 统 基 础 2/54 第 6 章 数 据 库 管 理 与 维 护

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

11.2 overview

untitled

PowerPoint Template

第 3 章选择结构 q q q Python 中表示条件的方法 if 语句 选择结构程序设计方法

ebook4-附录C

最佳实践产品文档

月光迴旋曲

Transcription:

第 4 章单表查询 学习目标 u 掌握简单查询, 会使用 SELECT 语句查询所有字段和指定的字段 u 掌握按条件查询, 会使用运算符以及不同的关键字进行查询 u 掌握高级查询, 会使用聚合函数查询 分组查询等 u 学会为表和字段起别名 通过前面章节的学习, 我们知道如何对数据进行添加 修改 删除等操作, 在数据库中还有一个更重要的操作就是查询数据, 查询数据是指从数据库中获取所需要的数据, 用户可以根据自己对数据的需求来查询不同的数据 本章将重点讲解如何针对 MySQL 数据库中的一张表进行查询 4.1 简单查询 4.1.1 SELECT 语句 MySQL 从数据表中查询数据的基本语句是 SELECT 语句 在 SELECT 语句中, 可以根据自己对数据的需求, 使用不同的查询条件,SELECT 语句的基本语法格式如下 : SELECT [DISTINCT] * { 字段名 1, 字段名 2, 字段名 3, } FROM 表名 [WHERE 条件表达式 1] [GROUP BY 字段名 [HAVING 条件表达式 2]] [ORDER BY 字段名 [ASC DESC]] [LIMIT [OFFSET] 记录数 ] 从上述语法格式可以看出, 一个 SELECT 语句由多个子句组成, 其各子句的含义如下 : l SELECT [DISTINCT] * { 字段名 1, 字段名 2, }: 字段 1, 字段 2 表示从表中查询的指定字段, 星号 ( * ) 通配符表示表中所有字段, 两者为互斥关系, 任选其一 DISTINCT 是可选参数, 用于剔除查询结果中重复的数据 l FROM 表名 : 表示从指定的表中查询数据 l WHERE 条件表达式 1: WHERE 是可选参数, 用于指定查询条件 l GROUP BY 字段名 [HAVING 条件表达式 2]: GROUP BY 是可选参数, 用于将查询结果按照指定字段进行分组, HAVING 也是可选参数, 用于对分组后的结果进行过滤 1

l ORDER BY 字段名 [ASC DESC]: ORDER BY 是可选参数, 用于将查询结果按照指定字段进行排序 排序方式由参数 ASC 或 DESC 控制, 其中 ASC 表示按升序进行排列,DESC 表示按降序进行排列 如果不指定参数, 默认为升序排列 l LIMIT [OFFSET] 记录数 : LIMIT 是可选参数, 用于限制查询结果的数量 LIMIT 后面可以跟 2 个参数, 第一个参数 OFFSET 表示偏移量, 如果偏移量为 0 则从查询结果的第一条记录开始, 偏移量为 1 则从查询结果的中第二条记录开始 以此类推 OFFSET 为可选值, 如果不指定其默认值为 0 第二个参数 记录数 表示返回查询记录的条数 SELECT 语句相对来说比较复杂, 对于初学者来说目前可能无法完全理解, 在本章中将通过具体的案例对 SELECT 语句的各个部分进行逐一讲解 4.1.2 查询所有字段 查询所有字段是指查询表中所有字段的数据,MySQL 中有两种方式可以查询表中所有字段, 接下来将针对这两种方式进行详细地讲解 1 在 SELECT 语句中指定所有字段在 SELECT 语句中列出所有字段名来查询表中的数据, 其语法格式如下 : SELECT 字段名 1, 字段名 2, FROM 表名在上述语法格式中, 字段名 1 字段名 2 表示查询的字段名, 这里需要列出表中所有的字段名 例 4-1 查询 student 表中的所有记录 为了实现查询功能, 首先创建一个数据库 chapter04, 创建数据库的 SQL 语句如下所示 : CREATE DATABASE chapter04; 选择使用 chapter04 数据库,SQL 语句如下所示 : USE chapter04; 在数据库 chapter04 中创建表 student, 创建 student 表的 SQL 语句如下所示 : CREATE TABLE student( id INT(3) PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL, grade FLOAT, gender CHAR(2) ); 执行 SQL 语句创建 student 表, 然后使用 INSERT 语句向 student 表中插入 8 条记录,INSERT 语句如下所示 : INSERT INTO student(name,grade,gender) VALUES('songjiang',40,' 男 '), ('wuyong',100,' 男 '), ('qinming',90,' 男 '), ('husanniang',88,' 女 '), ('sunerniang',66,' 女 '), ('wusong',86,' 男 '), ('linchong',92,' 男 '), 2

('yanqing',90,null); INSERT 语句执行成功后, 接下来通过 SELECT 语句查询 student 表中的记录,SQL 语句如下所示 : SELECT id,name,grade,gender FROM student; 查询结果如下所示 : mysql> SELECT id,name,grade,gender FROM student; 1 songjiang 40 男 2 wuyong 100 男 3 qinming 90 男 4 husanniang 88 女 5 sunerniang 66 女 6 wusong 86 男 7 linchong 92 男 8 yanqing 90 NULL 8 rows in set (0.00 sec) 从查询结果可以看出,SELECT 语句成功地查出了表中所有字段的数据 需要注意的是, 在 SELECT 语句的查询字段列表中, 字段的顺序是可以改变的, 无需按照其表中定义的顺序进行排列, 例如, 在 SELECT 语句中将 name 字段放在查询列表的最后一列, mysql> SELECT id,grade,gender,name FROM student; +----+-------+--------+------------+ id grade gender name +----+-------+--------+------------+ 1 40 男 songjiang 2 100 男 wuyong 3 90 男 qinming 4 88 女 husanniang 5 66 女 sunerniang 6 86 男 wusong 7 92 男 linchong 8 90 NULL yanqing +----+-------+--------+------------+ 8 rows in set (0.00 sec) 从查询结果可以看出, 在 SELECT 语句中将 name 字段放在最后一列, 其查询结果中 name 字段的数 据会在最后一列显示 2 在 SELECT 语句中使用星号 ( * ) 通配符代替所有字段 MySQL 中可以使用星号 ( * ) 通配符来代替所有的字段名, 其语法格式如下所示 : SELECT * FROM 表名 ; 例 4-2 在 SELECT 语句中使用星号 ( * ) 通配符查询 student 表中的所有字段,SQL 语句如下所 示 : SELECT * FROM student; 查询结果如下所示 : 3

mysql> SELECT * FROM student; 1 songjiang 40 男 2 wuyong 100 男 3 qinming 90 男 4 husanniang 88 女 5 sunerniang 66 女 6 wusong 86 男 7 linchong 92 男 8 yanqing 90 NULL 8 rows in set (0.01 sec) 从查询结果可以看出, 使用星号 ( * ) 通配符同样可以查出表中所有字段的数据, 这种方式比较简单, 但查询结果只能按照字段在表中定义的顺序显示 注意 : 一般情况下, 除非需要使用表中所有字段的数据, 否则最好不要使用星号通配符, 使用通配符虽然可 以节省输入查询语句的时间, 但由于获取的数据过多会降低查询的效率 4.1.3 查询指定字段 查询数据时, 可以在 SELECT 语句的字段列表中指定要查询的字段, 这种方式只针对部分字段进行查 询, 不会查询所有字段, 其语法格式如下所示 : SELECT 字段名 1, 字段名 2, FROM 表名 ; 在上面的语法格式中 字段名 1, 字段名 2, 表示表中的字段名称, 这里只需指定表中部分字段的 名称 例 4-3 使用 SELECT 语句查询 student 表中 name 字段和 gender 字段的数据, mysql> SELECT name,gender FROM student; +------------+--------+ name gender +------------+--------+ songjiang 男 wuyong 男 qinming 男 husanniang 女 sunerniang 女 wusong 男 linchong 男 yanqing NULL +------------+--------+ 8 rows in set (0.00 sec) 从查询结果可以看到, 只查询了 name 字段和 gender 字段的数据 如果在 SELECT 语句中改变查询字 4

段的顺序, 查询结果中字段显示的顺序也会做相应改变, 例如, 将 SELECT 语句中的 name 字段和 gender 字段位置互换, mysql> SELECT gender,name FROM student; +--------+------------+ gender name +--------+------------+ 男 songjiang 男 wuyong 男 qinming 女 husanniang 女 sunerniang 男 wusong 男 linchong NULL yanqing +--------+------------+ 8 rows in set (0.05 sec) 从查询结果可以看出, 字段显示的顺序和其在 SELECT 语句中指定的顺序一致 4.2 按条件查询 数据库中包含大量的数据, 很多时候需要根据需求获取指定的数据, 或者对查询的数据重新进行排列 组合, 这时就要在 SELECT 语句中指定查询条件对查询结果进行过滤, 本节将针对 SELECT 语句中使用的 查询条件进行详细地讲解 4.2.1 带关系运算符的查询 在 SELECT 语句中, 最常见的是使用 WHERE 子句指定查询条件对数据进行过滤, 其语法格式如下 : SELECT 字段名 1, 字段名 2, FROM 表名 WHERE 条件表达式在上面的语法格式中, 条件表达式 是指 SELECT 语句的查询条件 在 MySQL 中, 提供了一系列的关系运算符, 在 WHERE 子句中可以使用关系运算符连接操作数作为查询条件对数据进行过滤, 常见的关系运算符如表 4-1 所示 : 表 4-1 关系运算符关系运算符说明 = 等于 <> 不等于!= 不等于 < 小于 <= 小于等于 > 大于 >= 大于等于 5

表 4-1 中的关系运算符大家都比较熟悉, 需要说明的是 <> 运算符和!= 等价, 都表示不等于 接下来以表 4-1 中的 = > 关系运算符为例, 将它们作为查询条件对数据进行过滤 例 4-4 查询 student 表中 id 为 4 的学生姓名,SQL 语句如下所示 : SELECT id,name FROM student WHERE id=4; 在 SELECT 语句中使用 = 运算符获取 id 值为 4 的数据, 执行 SELECT 语句, 结果如下所示 : mysql> SELECT id,name FROM student WHERE id=4; +----+------------+ id name +----+------------+ 4 husanniang +----+------------+ 1 row in set (0.00 sec) 从查询结果可以看到,id 为 4 的学生姓名为 husanniang, 其它均不满足查询条件 例 4-5 使用 SELECT 语句查询 name 为 wusong 的学生性别, mysql> SELECT name,gender FROM student WHERE name='wusong'; +--------+--------+ name gender +--------+--------+ wusong 男 +--------+--------+ 1 row in set (0.01 sec) 从查询结果可以看到, 姓名为 wusong 的记录只有一条, 其性别为 男 例 4-6 查询 student 表中 grade 大于 80 的学生姓名,SQL 语句如下所示 : SELECT name,grade FROM student WHERE grade>80; 在 SELECT 语句中使用 > 运算符获取 grade 值大于 80 的数据, 执行 SELECT 语句, 结果如下所示 : mysql> SELECT name,grade FROM student WHERE grade>80; +------------+-------+ name grade +------------+-------+ wuyong 100 qinming 90 husanniang 88 wusong 86 linchong 92 yanqing 90 +------------+-------+ 6 rows in set (0.00 sec) 从查询结果可以看到, 所有记录的 grade 字段值均大于 80, 而小于或等于 80 的记录不会被显示 通过以上 3 个实例, 我们可以看出, 在查询条件中, 如果字段的类型为整型直接书写内容, 如果字段类型为字符串, 需要在字符串上使用单引号, 例如 : wusong 6

4.2.2 带 IN 关键字的查询 IN 关键字用于判断某个字段的值是否在指定集合中, 如果字段的值在集合中, 则满足条件, 该字段所在的记录将被查询出来 其语法格式如下所示 : SELECT * 字段名 1, 字段名 2, FROM 表名 WHERE 字段名 [NOT] IN ( 元素 1, 元素 2, ) 在上面的语法格式中, 元素 1 元素 2 表示集合中的元素, 即指定的条件范围 NOT 是可选参数, 使用 NOT 表示查询不在 IN 关键字指定集合范围中的记录 例 4-7 查询 student 表中 id 值为 1 2 3 的记录,SQL 语句如下所示 : SELECT id,grade,name,gender FROM student WHERE id IN(1,2,3); mysql> SELECT id,grade,name,gender FROM student WHERE id IN(1,2,3); +----+-------+-----------+--------+ id grade name gender +----+-------+-----------+--------+ 1 40 songjiang 男 2 100 wuyong 男 3 90 qinming 男 +----+-------+-----------+--------+ 3 rows in set (0.00 sec) 相反, 在关键字 IN 之前使用 NOT 关键字可以查询不在指定集合范围内的记录 例 4-8 查询 student 表中 id 值不为 1 2 3 的记录,SQL 语句如下所示 : SELECT id,grade,name,gender FROM student WHERE id NOT IN(1,2,3); mysql> SELECT id,grade,name,gender FROM student WHERE id NOT IN(1,2,3); +----+-------+------------+--------+ id grade name gender +----+-------+------------+--------+ 4 88 husanniang 女 5 66 sunerniang 女 6 86 wusong 男 7 92 linchong 男 8 90 yanqing NULL +----+-------+------------+--------+ 5 rows in set (0.00 sec) 从查询结果可以看到, 在 IN 关键字前使用了 NOT 关键字, 查询的结果与例 4-7 中的查询结果正好相反, 查出了 id 字段值不为 1 2 3 的所有记录 4.2.3 带 BETWEEN AND 关键字的查询 BETWEEN AND 用于判断某个字段的值是否在指定的范围之内, 如果字段的值在指定范围内, 则满足 7

条件, 该字段所在的记录将被查询出来, 反之则不会被查询出来 其语法格式如下所示 : SELECT * { 字段名 1, 字段名 2, } FROM 表名 WHERE 字段名 [NOT] BETWEEN 值 1 AND 值 2 在上面的语法格式中, 值 1 表示范围条件的起始值, 值 2 表示范围条件的结束值 NOT 是可选参数, 使用 NOT 表示查询指定范围之外的记录, 通常情况下 值 1 小于 值 2, 否则查询不到任何结果 例 4-9 查询 student 表中 id 值在 2 和 5 之间的学生姓名,SQL 语句如下所示 : SELECT id,name FROM student WHERE id BETWEEN 2 AND 5; mysql> SELECT id,name FROM student WHERE id BETWEEN 2 AND 5; +----+------------+ id name +----+------------+ 2 wuyong 3 qinming 4 husanniang 5 sunerniang +----+------------+ 4 rows in set (0.00 sec) 从查询结果可以看到, 查出了 id 字段值在 2 和 5 之间的所有记录, 并且起始值 2 和结束值 5 也包括在内 BETWEEN AND 之前可以使用 NOT 关键字, 用来查询指定范围之外的记录 例 4-10 查询 student 表中 id 值不在 2 和 5 之间的学生姓名,SQL 语句如下所示 : SELECT id,name FROM student WHERE id NOT BETWEEN 2 AND 5; mysql> SELECT id,name FROM student WHERE id NOT BETWEEN 2 AND 5; +----+-----------+ id name +----+-----------+ 1 songjiang 6 wusong 7 linchong 8 yanqing +----+-----------+ 4 rows in set (0.00 sec) 从查询结果可以看出, 查出记录的 id 字段值均小于 2 或者大于 5 4.2.4 空值查询 在数据表中, 某些列的值可能为空值 (NULL), 空值不同于 0, 也不同于空字符串 在 MySQL 中, 使用 IS NULL 关键字来判断字段的值是否为空值, 其语法格式如下所示 : SELECT * 字段名 1, 字段名 2, 8

FROM 表名 WHERE 字段名 IS [NOT] NULL 在上面的语法格式中, NOT 是可选参数, 使用 NOT 关键字用于判断字段不是空值 例 4-11 查询 student 表中 gender 为空值的记录,SQL 语句如下所示 : SELECT id,name,grade,gender FROM student WHERE gender IS NULL; mysql> SELECT id,name,grade,gender FROM student WHERE gender IS NULL; +----+---------+-------+--------+ +----+---------+-------+--------+ 8 yanqing 90 NULL +----+---------+-------+--------+ 1 row in set (0.00 sec) 从查询结果可以看到 gender 字段为空值, 满足查询条件 在关键字 IS 和 NULL 之间可以使用 NOT 关键字, 用来查询字段不为空值的记录, 接下来通过具体的案例来演示 例 4-12 查询 student 表中 gender 不为空值的记录,SQL 语句如下所示 : SELECT id,name,grade,gender FROM student WHERE gender IS NOT NULL; mysql> SELECT id,name,grade,gender FROM student WHERE gender IS NOT NULL; 1 songjiang 40 男 2 wuyong 100 男 3 qinming 90 男 4 husanniang 88 女 5 sunerniang 66 女 6 wusong 86 男 7 linchong 92 男 7 rows in set (0.00 sec) 从查询结果可以看到, 所有记录的 gender 字段值都不为空值 4.2.5 带 DISTINCT 关键字的查询 表中某些字段的数据存在重复的值, 例如 student 表中的 gender 字段, 使用 SELECT 语句查询 gender 字段, mysql> SELECT gender FROM student; +--------+ gender +--------+ 男 9

男 男 女 女 男 男 NULL +--------+ 8 rows in set (0.06 sec) 从查询结果可以看到, 查出的 8 条记录中有 5 条记录的 gender 字段值为 男, 两条记录的 gender 字 段值为 女 有时候, 出于对数据的分析需求, 需要去掉查询记录中重复的值, 在 SELECT 语句中, 可 以使用 DISTINCT 关键字来实现这种功能, 使用 DISTINCT 关键字的 SELECT 语句其语法格式如下 : SELECT DISTINCT 字段名 FROM 表名 ; 在上面的语法格式中, 字段名 表示要去除重复记录的字段 例 4-13 查询 student 表中 gender 字段的值, 查询记录不能重复,SQL 语句如下所示 : SELECT DISTINCT gender FROM student; mysql> SELECT DISTINCT gender FROM student; +--------+ gender +--------+ 男 女 NULL +--------+ 3 rows in set (0.01 sec) 从查询记录可以看到, 这次查询只返回了 3 条记录的 gender 值, 分别为 男 女 和 NULL, 不 再有重复值 & 多学一招 :DISTINCT 关键字作用多个字段 DISTINCT 关键字可以作用于多个字段, 其语法格式如下所示 : SELECT DISTINCT 字段名 1, 字段名 2, FROM 表名 ; 在上面的语法格式中, 只有 DISTINCT 关键字后指定的多个字段值都相同, 才会被认作是重复记录 例 4-14 查询 student 表中的 gender 和 name 字段, 使用 distinct 关键字作用于这两个字段,SQL 语 句如下所示 : SELECT DISTINCT gender,name FROM student; mysql> SELECT DISTINCT gender,name FROM student; +--------+------------+ gender name +--------+------------+ 男 songjiang 男 wuyong 10

男 qinming 女 husanniang 女 sunerniang 男 wusong 男 linchong NULL yanqing +--------+------------+ 8 rows in set (0.00 sec) 从查询结果可以看到, 返回的记录中 gender 字段仍然出现了重复值, 这是因为 DISTINCT 关键字作用 于 gender 和 name 两个字段, 只有这两个字段的值都相同才被认为是重复记录 而从上面的结果来看,gender 字段值重复的记录中, 它们的 name 字段值并不相同 为了能够演示去除多个字段重复的效果, 向 student 表中添加一条新记录,SQL 语句如下所示 : INSERT INTO student(name,grade,gender) VALUES('songjiang',20,' 男 '); 执行完 INSERT 语句后, 使用 SELECT 语句查询 student 表中的所有记录, mysql> SELECT * FROM student; 1 songjiang 40 男 2 wuyong 100 男 3 qinming 90 男 4 husanniang 88 女 5 sunerniang 66 女 6 wusong 86 男 7 linchong 92 男 8 yanqing 90 NULL 9 songjiang 20 男 9 rows in set (0.00 sec) 从查询结果可以看到,student 表中一共有 9 条记录, 并且第 1 条记录 第 9 条记录的 name 字段和 gender 字段值相等, 分别为 songjiang 和 男 接下来再次查询 gender 和 name 字段, 并使用 distinct 作用这 两个字段, mysql> SELECT DISTINCT gender,name FROM student; +--------+------------+ gender name +--------+------------+ 男 songjiang 男 wuyong 男 qinming 女 husanniang 女 sunerniang 男 wusong 男 linchong 11

NULL yanqing +--------+------------+ 8 rows in set (0.00 sec) 从查询结果可以看到, 只查出了 8 条记录, 并且 gender 字段值为 男, name 字段值为 songjiang 的记录只有一条, 这说明 DISTINCT 去除了重复的记录 4.2.6 带 LIKE 关键字的查询 前面的小节中讲过, 使用关系运算符 = 可以判断两个字符串是否相等, 但有时候我们需要对字符串进行模糊查询, 例如查询 student 表中 name 字段值以字符 b 开头的记录, 为了完成这种功能,MySQL 中提供了 LIKE 关键字,LIKE 关键字可以判断两个字符串是否相匹配 使用 LIKE 关键字的 SELECT 语句其语法格式如下所示 : SELECT * { 字段名 1, 字段名 2, } FROM 表名 WHERE 字段名 [NOT] LIKE ' 匹配字符串 '; 在上面的语法格式中,NOT 是可选参数, 使用 NOT 表示查询与指定字符串不匹配的记录 匹配字符串 指定用来匹配的字符串, 其值可以是一个普通字符串, 也可以是包含百分号 (%) 和下划线 (_) 的通配字符串 百分号和下划线统称为通配符, 它们在通配字符串中有特殊含义, 两者的作用如下所示 : 1 百分号(%) 通配符 : 匹配任意长度的字符串, 包括空字符串 例如, 字符串 c% 匹配以字符 c 开始, 任意长度的字符串, 如 ct cut current 等 例 4-15 查找 student 表中 name 字段值以字符 s 开头的学生 id,sql 语句如下所示 : SELECT id,name FROM student WHERE name LIKE "s%"; mysql> SELECT id,name FROM student WHERE name LIKE "s%"; +----+------------+ id name +----+------------+ 1 songjiang 5 sunerniang +----+------------+ 2 rows in set (0.00 sec) 从查询结果可以看到, 返回的记录中 name 字段值均以字符 s 开头, s 后面可以跟任意数量的字符 百分号通配符可以出现在通配字符串的任意位置 例 4-16 查询 student 表中 name 字段值以字符 w 开始, 以字符 g 结束的学生 id, mysql> SELECT id,name FROM student WHERE name LIKE 'w%g'; +----+--------+ id name +----+--------+ 2 wuyong 12

6 wusong +----+--------+ 2 rows in set (0.00 sec) 从查询结果可以看到, 字符 w 和 g 之间的百分号通配符匹配两个字符之间任意个数的字符 在通配字符串中可以出现多个百分号通配符 例 4-17 查询 student 表中 name 字段值包含字符 y 的学生 id, mysql> SELECT id,name FROM student WHERE name LIKE '%y%'; +----+---------+ id name +----+---------+ 2 wuyong 8 yanqing +----+---------+ 2 rows in set (0.02 sec) 从查询结果可以看到, 通配字符串中的字符 y 前后各有一个百分号通配符, 它匹配包含字符 y 的字符串, 无论 y 在字符串的什么位置 LIKE 之前可以使用 NOT 关键字, 用来查询与指定通配字符串不匹配的记录 例 4-18 查询 student 表中 name 字段值不包含字符 y 的学生 id, mysql> SELECT id,name FROM student WHERE name NOT LIKE '%y%'; +----+------------+ id name +----+------------+ 1 songjiang 3 qinming 4 husanniang 5 sunerniang 6 wusong 7 linchong +----+------------+ 6 rows in set (0.00 sec) 从查询结果可以看出, 返回的记录中 name 字段值都不包含字符 y, 正好和例 4-17 的查询结果相反 2 下划线(_) 通配符 : 下划线通配符与百分号通配符有些不同, 下划线通配符只匹配单个字符, 如果要匹配多个字符, 需要使用多个下划线通配符 例如, 字符串 cu_ 匹配以字符串 cu 开始, 长度为 3 的字符串, 如 cut cup, 字符串 c l 匹配在字符 c 和 l 之间包含两个字符的字符串, 如 cool coal 等 需要注意的是, 如果使用多个下划线匹配多个连续的字符, 下划线之间不能有空格, 例如, 通配字符串 M QL 只能匹配字符串 My SQL, 而不能匹配字符串 MySQL 例 4-19 查询 student 表中 name 字段值以字符串 wu 开始, 以字符串 ong 结束, 并且两个字符串之间只有一个字符的记录,SQL 语句如下所示 : SELECT * FROM student WHERE name LIKE 'wu_ong'; mysql> SELECT * FROM student WHERE name LIKE 'wu_ong'; +----+--------+-------+--------+ 13

+----+--------+-------+--------+ 2 wuyong 100 男 6 wusong 86 男 +----+--------+-------+--------+ 2 rows in set (0.00 sec) 从查询结果可以看出, 查出的记录中 name 字段值为 wuyong 和 wusong, 通配字符串 wu_ong 中一个下划线匹配了一个字符 对上述的 SQL 语句进行修改, 将匹配字符串修改为 wu_ng, 再次执行 查询语句, 符 mysql> SELECT * FROM student WHERE name LIKE 'wu_ng'; Empty set (0.00 sec) 从查询结果可以看到返回记录为空, 这是因为匹配字符串中只有一个下划线通配符, 无法匹配两个字 例 4-20 查询 student 表中 name 字段值包含 7 个字符, 并且以字符串 ing 结束的记录, 执行结 果如下所示 : mysql> SELECT * FROM student WHERE name LIKE ' ing'; +----+---------+-------+--------+ +----+---------+-------+--------+ 3 qinming 90 男 8 yanqing 90 NULL +----+---------+-------+--------+ 2 rows in set (0.01 sec) 从查询结果可以看到, 在通配字符串中使用了 4 个下划线通配符, 它匹配 name 字段值中 ing 前面 的 4 个字符 & 多学一招 : 使用百分号和下划线通配符进行查询操作 百分号和下划线是通配符, 它们在通配字符串中有特殊含义, 因此, 如果要匹配字符串中的百分号和 下划线, 就需要在通配字符串中使用右斜线 ( \ ) 对百分号和下划线进行转义, 例如, \% 匹配百分号 字面值, \_ 匹配下划线字面值 例 4-21 查询 student 表中 name 字段值包括 % 的记录 在查询之前, 首先向 student 表中添加一条记录, mysql> INSERT INTO student(name,grade,gender) -> VALUES('sun%er',95,' 男 '); Query OK, 1 row affected (0.00 sec) 从上面的执行语句中可以看到, 添加的新记录其 name 字段值为 sun%er, 包含一个百分号字面值 接下来通过 SELECT 语句查出这条记录,SQL 语句如下所示 : SELECT * FROM student WHERE name LIKE '%\%%'; 从上面的执行语句可以看到, 在通配字符串 %\%% 中, \% 匹配百分号字面值, 第一个和第三个 百分号匹配任意个数的字符, mysql> SELECT * FROM student WHERE name LIKE '%\%%'; +----+--------+-------+--------+ +----+--------+-------+--------+ 14

10 sun%er 95 男 +----+--------+-------+--------+ 1 row in set (0.00 sec) 从查询结果可以看到, 查出了 name 字段值为 sun%er 的新记录 4.2.7 带 AND 关键字的多条件查询 在使用 SELECT 语句查询数据时, 有时为了使查询结果更加精确, 可以使用多个查询条件 在 MySQL 中, 提供了一个 AND 关键字, 使用 AND 关键字可以连接两个或者多个查询条件, 只有满足所有条件的记录才会被返回 其语法格式如下所示 : SELECT * { 字段名 1, 字段名 2, } FROM 表名 WHERE 条件表达式 1 AND 条件表达式 2 [ AND 条件表达式 n]; 从上面的语法格式可以看到, 在 WHERE 关键字后面跟了多个条件表达式, 每两个条件表达式之间用 AND 关键字分隔 例 4-22 查询 student 表中 id 字段值小于 5, 并且 gender 字段值为 女 的学生姓名,SQL 语句如下所示 : SELECT id,name,gender FROM student WHERE id<5 AND gender=' 女 '; mysql> SELECT id,name,gender FROM student WHERE id<5 AND gender=' 女 '; +----+------------+--------+ id name gender +----+------------+--------+ 4 husanniang 女 +----+------------+--------+ 1 row in set (0.00 sec) 从查询结果可以看到, 返回记录的 id 字段值为 4,gender 字段值为 女, 也就是说, 查询结果必须同时满足 AND 关键字连接的两个条件表达式 例 4-23 查询 student 表中 id 字段值在 1 2 3 4 之中,name 字段值以字符串 ng 结束, 并且 grade 字段值小于 80 的记录,SQL 语句如下所示 : SELECT id,name,grade,gender FROM student WHERE id in(1,2,3,4) AND name LIKE '%ng' AND grade<80; 在 SELECT 语句中, 使用两个 AND 关键字连接了三个条件表达式, mysql> SELECT id,name,grade,gender -> FROM student -> WHERE id in(1,2,3,4) AND name LIKE '%ng' AND grade<80; +----+-----------+-------+--------+ +----+-----------+-------+--------+ 1 songjiang 40 男 +----+-----------+-------+--------+ 1 row in set (0.00 sec) 15

从查询结果可以看出, 返回的记录同时满足 AND 关键字连接的 3 个条件表达式 4.2.8 带 OR 关键字的多条件查询 在使用 SELECT 语句查询数据时, 也可以使用 OR 关键字连接多个查询条件 与 AND 关键字不同, 在使用 OR 关键字时, 只要记录满足任意一个条件就会被查询出来 其语法格式如下所示 : SELECT * { 字段名 1, 字段名 2, } FROM 表名 WHERE 条件表达式 1 OR 条件表达式 2 [ OR 条件表达式 n]; 从上面的语法格式可以看到, 在 WHERE 关键字后面跟了多个条件表达式, 每两个条件表达式之间用 OR 关键字分隔 例 4-24 查询 student 表中 id 字段值小于 3 或者 gender 字段值为 女 的学生姓名,SQL 语句如下所示 : SELECT id,name,gender FROM student WHERE id<3 OR gender=' 女 '; mysql> SELECT id,name,gender FROM student WHERE id<3 OR gender=' 女 '; +----+------------+--------+ id name gender +----+------------+--------+ 1 songjiang 男 2 wuyong 男 4 husanniang 女 5 sunerniang 女 +----+------------+--------+ 4 rows in set (0.02 sec) 从查询结果可以看到, 返回的 4 条记录中, 其中两条是 id 字段值小于 3 的记录, 其 gender 字段值为 男, 两条 gender 字段值为 女 的记录, 其 id 值大于 3 这就说明, 只要记录满足 OR 关键字连接的任意一个条件就会被查询出来, 而不需要同时满足两个条件表达式 例 4-25 查询 student 表中满足条件 name 字段值以字符 h 开始, 或者 gender 字段值为 女, 或者 grade 字段值为 100 的记录,SQL 语句如下所示 : SELECT id,name,grade,gender FROM student WHERE name LIKE 'h%' OR gender=' 女 ' OR grade=100; mysql> SELECT id,name,grade,gender -> FROM student -> WHERE name LIKE 'h%' OR gender=' 女 ' OR grade=100; 2 wuyong 100 男 4 husanniang 88 女 5 sunerniang 66 女 16

3 rows in set (0.00 sec) 从查询结果可以看到, 返回的 3 条记录至少满足 OR 关键字连接的 3 个条件之一 & 多学一招 :OR 和 AND 关键字一起使用的情况 OR 关键字和 AND 关键字可以一起使用, 需要注意的是,AND 的优先级高于 OR, 因此当两者在一起 使用时, 应该先运算 AND 两边的条件表达式, 再运算 OR 两边的条件表达式 例 4-21 查询 student 表中 gender 字段值为 女 或者 gender 字段值为 男, 并且 grade 字段值为 100, 的学生姓名,SQL 语句如下所示 : SELECT name,grade,gender FROM student WHERE gender=' 女 ' OR gender=' 男 ' AND grade=100; mysql> SELECT name,grade,gender -> FROM student -> WHERE gender=' 女 ' OR gender=' 男 ' AND grade=100; +------------+-------+--------+ name grade gender +------------+-------+--------+ wuyong 100 男 husanniang 88 女 sunerniang 66 女 +------------+-------+--------+ 3 rows in set (0.00 sec) 从查询结果可以看到, 如果 AND 的优先级和 OR 相同或者比 OR 低,AND 操作会最后执行, 查询结 果只会返回一条记录, 记录的 grade 字段值为 100 而本例中返回了三条记录, 这说明先执行的是 AND 操 作, 后执行的是 OR 操作, 即 AND 的优先级高于 OR 4.3 高级查询 4.3.1 聚合函数 实际开发中, 经常需要对某些数据进行统计, 例如统计某个字段的最大值 最小值 平均值等等, 为此,MySQL 中提供了一些函数来实现这些功能, 具体如表 4-2 所示 表 4-2 聚合函数函数名称作用 COUNT() 返回某列的行数 SUM() 返回某列值的和 AVG() 返回某列的平均值 MAX() 返回某列的最大值 MIN() 返回某列的最小值表 4-2 中的函数用于对一组值进行统计, 并返回唯一值, 这些函数被称为聚合函数, 下面就对聚合函 17

数的用法进行讲解 1 COUNT() 函数 COUNT() 函数用来统计记录的条数, 其语法格式如下所示 : SELECT COUNT(*) FROM 表名使用上面的语法格式可以求出表中有多少条记录 例 4-22 查询 student 表中一共有多少条记录,SQL 语句如下所示 : SELECT COUNT(*) FROM student; mysql> SELECT COUNT(*) FROM student; +----------+ COUNT(*) +----------+ 8 +----------+ 1 row in set (0.06 sec) 从查询结果可以看出,student 表中一共有 8 条记录 2 SUM() 函数 SUM() 是求和函数, 用于求出表中某个字段所有值的总和, 其语法格式如下 : SELECT SUM( 字段名 ) FROM 表名 ; 使用上面的语句可以求出指定字段值的总和 例 4-23 求出 student 表中 grade 字段的总和,SQL 语句如下所示 : SELECT SUM(grade) FROM student; mysql> SELECT SUM(grade) FROM student; +------------+ SUM(grade) +------------+ 652 +------------+ 1 row in set (0.00 sec) 从查询结果可以看到, 所有学生 grade 字段的总和为 652 3 AVG() 函数 AVG() 函数用于求出某个字段所有值的平均值, 其语法格式如下所示 : SELECT AVG( 字段名 ) FROM student; 使用上面的语句可以求出指定字段所有值的平均值 例 4-24 求出 student 表中 grade 字段的平均值,SQL 语句如下所示 : SELECT AVG(grade) FROM student; mysql> SELECT AVG(grade) FROM student; +------------+ AVG(grade) +------------+ 81.5 +------------+ 18

1 row in set (0.00 sec) 从查询结果可以看到, 所有学生 grade 字段的平均值为 81.5 4 MAX() 函数 MAX() 函数是求最大值的函数, 用于求出某个字段的最大值, 其语法格式如下所示 : SELECT MAX(grade) FROM student; 例 4-25 求出 student 表中所有学生 grade 字段的最大值,SQL 语句如下所示 : mysql> SELECT MAX(grade) FROM student; +------------+ MAX(grade) +------------+ 100 +------------+ 1 row in set (0.09 sec) 从查询结果可以看到, 所有学生 grade 字段的最大值为 100 5 MIN() 函数 MIN() 函数是求最小值的函数, 用于求出某个字段的最小值, 其语法格式如下所示 : SELECT MIN(grade) FROM student; 例 4-26 求出 student 表中 grade 字段的最小值,SQL 语句如下所示 : mysql> SELECT MIN(grade) FROM student; +------------+ MIN(grade) +------------+ 40 +------------+ 1 row in set (0.00 sec) 从查询结果可以看到, 所有学生 grade 字段的最小值为 40 4.3.2 对查询结果排序 从表中查询出来的数据可能是无序的, 或者其排列顺序不是用户期望的 为了使查询结果满足用户的要求, 可以使用 ORDER BY 对查询结果进行排序, 其语法格式如下所示 : SELECT 字段名 1, 字段名 2, FROM 表名 ORDER BY 字段名 1 [ASC DESC], 字段名 2 [ASC DESC] 在上面的语法格式中, 指定的字段名 1 字段名 2 等是对查询结果排序的依据 参数 ASC 表示按照升序进行排序,DESC 表示按照降序进行排序 默认情况下, 按照 ASC 方式进行排序 例 4-27 查出 student 表中的所有记录, 并按照 grade 字段进行排序,SQL 语句如下所示 : SELECT * FROM student ORDER BY grade; mysql> SELECT * FROM student -> ORDER BY grade; 19

1 songjiang 40 男 5 sunerniang 66 女 6 wusong 86 男 4 husanniang 88 女 3 qinming 90 男 8 yanqing 90 NULL 7 linchong 92 男 2 wuyong 100 男 8 rows in set (0.00 sec) 从查询结果可以看到, 返回的记录按照 ORDER BY 指定的字段 grade 进行排序, 并且默认是按升序排 列 例 4-28 查出 student 表中的所有记录, 使用参数 ASC 按照 grade 字段升序方式排列,SQL 语句如 下所示 : SELECT * FROM student ORDER BY grade ASC; mysql> SELECT * FROM student ORDER BY grade ASC; 1 songjiang 40 男 5 sunerniang 66 女 6 wusong 86 男 4 husanniang 88 女 3 qinming 90 男 8 yanqing 90 NULL 7 linchong 92 男 2 wuyong 100 男 8 rows in set (0.00 sec) 从查询结果可以看到, 在 ORDER BY 中使用了 ASC 关键字, 返回结果和例 4-27 查询的结果一致 例 4-29 查出 student 表中的所有记录, 使用参数 DESC 按照 grade 字段降序方式排列,SQL 语句如 下所示 : SELECT * FROM student ORDER BY grade DESC; mysql> SELECT * FROM student ORDER BY grade DESC; 2 wuyong 100 男 7 linchong 92 男 3 qinming 90 男 20

排列 8 yanqing 90 NULL 4 husanniang 88 女 6 wusong 86 男 5 sunerniang 66 女 1 songjiang 40 男 8 rows in set (0.00 sec) 从查询结果可以看到, 在 ORDER BY 中使用了 DESC 关键字, 返回的记录按照 grade 字段的降序进行 在 MySQL 中, 可以指定按照多个字段对查询结果进行排序, 例如, 将查出的 student 表中所有记录按 照 gender 和 grade 字段进行排序 在排序过程中, 会先按照 gender 字段进行排序, 如果遇到 gender 字段值 相同的记录, 再把这些记录按照 grade 字段进行排序 例 4-30 查询 student 表中的所有记录, 按照 gender 字段的升序和 grade 字段的降序进行排列,SQL 语句如下所示 : SELECT * FROM student ORDER BY gender ASC,grade DESC; mysql> SELECT * FROM student -> ORDER BY gender ASC,grade DESC; 8 yanqing 90 NULL 4 husanniang 88 女 5 sunerniang 66 女 2 wuyong 100 男 7 linchong 92 男 3 qinming 90 男 6 wusong 86 男 1 songjiang 40 男 8 rows in set (0.00 sec) 从查询记录可以看到, 返回的结果首先按照 gender 字段值的升序进行排序, 然后 gender 值为 男 和 女 的记录分别再按照 grade 字段值的降序进行排列 注意 : 在按照指定字段进行升序排列时, 如果某条记录的字段值为 NULL, 则这条记录会在第一条显示, 这 是因为 NULL 值可以被认为是最小值, 如例 4-30 中, 显示的第一条记录其 gender 字段值为 NULL 4.3.3 分组查询 在对表中数据进行统计时, 也可能需要按照一定的类别进行统计, 比如, 分别统计 student 表中 gender 字段值为 男 女 和 NULL 的学生成绩 (grade 字段 ) 之和 在 MySQL 中, 可以使用 GROUP BY 按某个字段或者多个字段中的值进行分组, 字段中值相同的为一组, 其语法格式如下所示 : 21

SELECT 字段名 1, 字段名 2, FROM 表名 GROUP BY 字段名 1, 字段名 2, [HAVING 条件表达式 ]; 在上面的语法格式中, 指定的字段名 1 字段名 2 等是对查询结果分组的依据 HAVING 关键字指定条件表达式对分组后的内容进行过滤 需要特别注意的是,GROUP BY 一般和聚合函数一起使用, 如果查询的字段出现在 GROUP BY 后, 却没有没有包含在聚合函数中, 该字段显示的是分组后的第一条记录的值, 这样有可能会导致查询结果不符合我们的预期 由于分组查询比较复杂, 接下来将分几种情况对分组查询进行讲解 1 单独使用 GROUP BY 分组单独使用 group by 关键字, 查询的是每个分组中的一条记录 例 4-31 查询 student 表中的记录, 按照 gender 字段值进行分组,SQL 语句如下所示 : SELECT * FROM student GROUP BY gender; mysql> SELECT * FROM student GROUP BY gender; 8 yanqing 90 NULL 4 husanniang 88 女 1 songjiang 40 男 3 rows in set (0.00 sec) 从查询结果可以看到返回了 3 条记录, 这三条记录中 gender 字段的值分别为 NULL 男 女, 这说明了查询结果是按照 gender 字段中不同的值进行分类 然而这样的查询结果只显示每个分组中的一条记录, 意义并不大, 一般情况下 GROUP BY 一般都和聚合函数一起使用 2 GROUP BY 和聚合函数一起使用 GROUP BY 和聚合函数一起使用, 可以统计出某个或者某些字段在一个分组中的最大值 最小值 平均值等等 例 4-32 将 student 表按照 gender 字段值进行分组查询, 计算出每个分组中各有多少名学生,SQL 语句如下所示 : SELECT COUNT(*),gender FROM student GROUP BY gender; mysql> SELECT COUNT(*),gender FROM student GROUP BY gender; +----------+--------+ COUNT(*) gender +----------+--------+ 1 NULL 2 女 5 男 +----------+--------+ 3 rows in set (0.00 sec) 从查询结果可以看到,GROUP BY 对 student 表按照 gender 字段中的不同值进行了分组, 并通过 COUNT() 函数统计出 gender 字段值为 NULL 的学生有 1 个,gender 字段值为 男 的学生有 5 个,gender 22

字段值为 女 的学生有 2 个 3 GROUP BY 和 HAVING 关键字一起使用 HAVING 关键字和 WHERE 关键字的作用相同, 都用于设置条件表达式对查询结果进行过滤, 两者的区别在于,HAVING 关键字后可以跟聚合函数, 而 WHERE 关键字不能 通常情况下 HAVING 关键字都和 GROUP BY 一起使用, 用于对分组后的结果进行过滤 例 4-33 将 student 表按照 gender 字段进行分组查询, 查询出 grade 字段值之和小于 300 的分组, SQL 语句如下所示 : SELECT sum(grade),gender FROM student GROUP BY gender HAVING SUM(grade)<300; mysql> SELECT sum(grade),gender FROM student GROUP BY gender HAVING SUM(grade)<300; +------------+--------+ sum(grade) gender +------------+--------+ 90 NULL 154 女 +------------+--------+ 2 rows in set (0.00 sec) 从查询结果可以看到, 只有 gender 值为 NULL 和 女 的分组其 grade 字段值之和小于 300 为了验证查询结果的正确性, 下面对 gender 值为 男 的所有学生其 grade 字段值之和进行查询, mysql> SELECT SUM(grade),gender FROM student WHERE gender=' 男 '; +------------+--------+ SUM(grade) gender +------------+--------+ 408 男 +------------+--------+ 1 row in set (0.00 sec) 从查询结果可以看到,gender 字段值为 男 的所有学生其 grade 字段值之和为 408, 可以说明上面分组查询结果的正确性 4.3.4 使用 LIMIT 限制查询结果的数量 查询数据时, 可能会返回很多条记录, 而用户需要的记录可能只是其中的一条或者几条, 比如实现分页功能, 每页显示 10 条信息, 每次查询就只需要查出 10 条记录 为此,MySQL 中提供了一个关键字 LIMIT, 可以指定查询结果从哪一条记录开始以及一共查询多少条信息, 其语法格式如下所示 : SELECT 字段名 1, 字段名 2, FROM 表名 LIMIT [OFFSET,] 记录数在上面的语法格式中,LIMIT 后面可以跟 2 个参数, 第一个参数 OFFSET 表示偏移量, 如果偏移量为 0 则从查询结果的第一条记录开始, 偏移量为 1 则从查询结果的第二条记录开始 以此类推 OFFSET 为可选值, 如果不指定其默认值为 0 第二个参数 记录数 表示返回查询记录的条数 例 4-34 查询 student 表中的前 4 条记录,SQL 语句如下所示 : 23

SELECT * FROM student LIMIT 4; mysql> SELECT * FROM student LIMIT 4; 1 songjiang 40 男 2 wuyong 100 男 3 qinming 90 男 4 husanniang 88 女 4 rows in set (0.00 sec) 从查询结果可以看到, 执行语句中没有指定返回记录的偏移量, 只指定了查询记录的条数 4, 因此返 回结果从第一条记录开始, 一共返回 4 条记录 例 4-35 查询 student 表中 grade 字段值从第 5 位到第 8 位的学生 ( 从高到低 ),SQL 语句如下所示 : SELECT * FROM student ORDER BY grade DESC LIMIT 4,4; 从上面的执行语句可以看到,LIMIT 后面跟了两个参数, 第一个参数表示偏移量为 4, 即从第 5 条记 录开始查询, 第二个参数表示一共返回 4 条记录, 即从第 5 位到第 8 位学生 使用 ORDER BY DES 为了使学生按照的 grade 字段值从高到低的顺序进行排列, mysql> SELECT * FROM student ORDER BY grade DESC LIMIT 4,4; 4 husanniang 88 女 6 wusong 86 男 5 sunerniang 66 女 1 songjiang 40 男 4 rows in set (0.00 sec) 从查询结果可以看到返回了 4 条记录, 为了验证返回记录的 grade 字段值是从第 5 位到第 8 位, 下面 对 student 表中所用记录按照 grade 字段从高到低的顺序进行排列, mysql> SELECT * FROM student ORDER BY grade DESC; 2 wuyong 100 男 7 linchong 92 男 3 qinming 90 男 8 yanqing 90 NULL 4 husanniang 88 女 6 wusong 86 男 5 sunerniang 66 女 1 songjiang 40 男 24

8 rows in set (0.00 sec) 通过对比可以看到使用 LIMIT 查询的结果正好是所有记录的第 5 位到第 8 位 4.3.5 函数 ( 列表 ) MySQL 中提供了丰富的函数, 通过这些函数可以简化用户对数据的操作 MySQL 中的函数包括数学 函数 字符串函数 日期和时间函数 条件判断函数 加密函数等等 由于函数数量较多, 不可能一一进 行讲解, 接下来通过 5 张表对其中一些常用函数的作用进行说明 表 4-3 数学函数 函数名称 作用 ABS(x) 返回 x 的绝对值 SQRT(x) 返回 x 的非负 2 次方根 MOD(x,y) 返回 x 被 y 除后的余数 CEILING(x) 返回不小于 x 的最小整数 FLOOR(x) 返回不大于 x 的最大整数 ROUND(x,y) 对 x 进行四舍五入操作, 小数点后保留 y 位 TRUNCATE(x) 舍去 x 中小数点 y 位后面的的数 SIGN(x) 返回 x 的符号,-1 0 或者 1 表 4-4 字符串函数 函数名称 作用 LENGTH(str) 返回字符串 str 的长度 CONCAT(s1,s2, ) 返回一个或者多个字符串连接产生的新的字符串 TRIM(str) 删除字符串两侧的空格 REPLACE(str,s1,s2) 使用字符串 s2 替换字符串 str 中所有的字符串 s1 SUBSTRING(str,n,len) 返回字符串 str 的子串, 起始位置为 n, 长度为 len REVERSE(str) 返回字符串反转后的结果 LOCATE(s1,str) 返回子串 s1 在字符串 str 中的起始位置 表 4-5 日期和时间函数 函数名称 作用 CURDATE() 获取系统当前日期 CURTIME() 获取系统当前时间 SYSDATE() 获取当前系统日期和时间 TIME_TO_SEC() 返回将时间转换成秒的结果 ADDDATE() 执行日期的加运算 SBUDATE() 执行日期的减运算 DATE_FORMAT() 格式化输出日期和时间值 表 4-6 条件判断函数 函数名称 作用 IF(expr,v1,v2) 如果 expr 表达式为 true 返回 v1, 否则返回 v2 IFNULL(v1,v2) 如果 v1 不为 NULL 返回 v1, 否则返回 v2 CASE expr WHEN v1 THEN r1 如果 expr 值等于 v1 v2 等, 则返回对应位置 THEN [WHEN v2 THEN r2 ] [ELSE rn] END 后面的结果, 否则返回 ELSE 后的结果 rn 25

表 4-7 加密函数 函数名称 作用 MD5(str) 对字符串 str 进行 MD5 加密 ENCODE(str,pwd_str) 使用 pwd 作为密码加密字符串 str DECODE(str,pwd_str) 使用 pwd 作为密码解密字符串 str 表 4-3 到 4-7 对 MySQL 中常用函数的用法做了介绍, 下面就以函数 CONCAT(s1,s2, ) 和 IF(expr, v1,v2 为例, 通过案例对这两个函数的使用进行演示 例 4-36 查询 student 表中的所有记录, 将各个字段值使用下划线 _ 连接起来,SQL 语句如下所 示 : SELECT CONCAT(id,'_',name,'_',grade,'_',gender) FROM student; 执行结果结果如下所示 : mysql> SELECT CONCAT(id,'_',name,'_',grade,'_',gender) FROM student; +------------------------------------------+ CONCAT(id,'_',name,'_',grade,'_',gender) +------------------------------------------+ 1_songjiang_40_ 男 2_wuyong_100_ 男 3_qinming_90_ 男 4_husanniang_88_ 女 5_sunerniang_66_ 女 6_wusong_86_ 男 7_linchong_92_ 男 NULL +------------------------------------------+ 8 rows in set (0.01 sec) 从查询结果可以看到, 通过调用 CONCAT 函数将 student 表中各个字段的值使用下滑线连接起来了 需要注意的是 :CONCAT(str1,str2, ) 返回结果为连接参数产生的字符串 如有任何一个参数为 NULL, 则返回值为 NULL 例 4-37 查询 student 表中的 id 和 gender 字段值, 如果 gender 字段的值为 男 则返回 1, 如果不 为 男 则返回 0,SQL 语句如下所示 : SELECT id,if(gender=' 男 ',1,0) FROM student; mysql> SELECT id,if(gender=' 男 ',1,0) FROM student; +----+---------------------+ id IF(gender=' 男 ',1,0) +----+---------------------+ 1 1 2 1 3 1 4 0 5 0 6 1 7 1 26

8 0 +----+---------------------+ 8 rows in set (0.00 sec) 从查询结果可以看到,student 表中 gender 字段值为 男 的记录都返回 1,gender 字段为 女 或者 NULL 的记录都返回 0 4.4 为表和字段取别名 在查询数据时, 可以为表和字段取别名, 这个别名可以代替其指定的表和字段 本小节将分别讲解如 何为表和字段取别名 4.4.1 为表取别名 在查询操作时, 如果表名很长使用起来就不太方便, 这时可以为表取一个别名, 用这个别名来代替表的名称 MySQL 中为表起别名的格式如下所示 : SELECT * FROM 表名 [AS] 别名 ; 在上面的语法格式中,AS 关键字用于指定表名的别名, 它可以省略不写 例 4-38 为 student 表起一个别名 s, 并查询 student 表中 gender 字段值为 女 的记录,SQL 语句如下所示 : SELECT * FROM student AS s WHERE s.gender=' 女 '; 在上面的执行语句中, student AS s 表示 student 表的别名为 s,s.gender 表示 student 表的 gender 字段, mysql> SELECT * FROM student AS s WHERE s.gender=' 女 '; 4 husanniang 88 女 5 sunerniang 66 女 2 rows in set (0.01 sec) 4.4.2 为字段取别名 在前面的查询操作中, 每条记录中的列名都是定义表时的字段名, 有时为了显示查询结果更加直观, 可以为字段取一个别名,MySQL 中为字段起别名的格式如下所示 : SELECT 字段名 [AS] 别名 [, 字段名 [AS] 别名, ] FROM 表名 ; 在上面的语法格式中, 为字段名指定别名的 AS 关键字也可以省略不写 例 4-39 查询 student 表中的所有记录的 name 和 gender 字段值, 并为这两个字段起别名 stu_name 和 stu_gender,sql 语句如下所示 : SELECT name AS stu_name,gender stu_gender FROM student; mysql> SELECT name AS stu_name,gender stu_gender FROM student; 27

+------------+------------+ stu_name stu_gender +------------+------------+ songjiang 男 wuyong 男 qinming 男 husanniang 女 sunerniang 女 wusong 男 linchong 男 yanqing NULL +------------+------------+ 8 rows in set (0.02 sec) 从查询结果可以看到, 显示的是指定的别名而不是 student 表中的字段名 4.5 本章小结 本章主要讲解了如何对单表进行简单查询 带条件查询和高级查询, 以及如何为表名和字段名取别名 其中数据查询是数据库操作中重点掌握的内容, 大家应该多加练习, 以便为以后章节的学习打下坚实基础 28