数据库专家第一步: MySQL 必知必会的知识总汇

本书全面介绍了SQL和MySQL的基础知识,包括数据库和SQL概念、MySQL的简介与工具、数据检索、排序、过滤、分组、联结等操作。通过实例详细解析了SELECT语句的使用,如WHERE子句、ORDER BY子句、子查询、联结等,并涵盖了正则表达式和计算字段的使用。内容深入浅出,适合数据库初学者和开发者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库专家第一步

第1章:了解 SQL

1. 什么是数据库?

数据库是一个以某种有组织的方式存储的数据集合。(文件柜)
或者说是保存有组织的数据的容器。
我们常常使用 DBMS(数据库管理系统软件) 来操作数据库!

  • 表: 某种特定类型数据的结构化清单。(单一数据库中唯一可标识)
  • 列和数据结构:列是表中的一个字段,所有表都是由一个或多个列组成的
  • 行:表中的数据是按行存储的,一行是一个数据库表中的一条记录。
  • 主键:一列(一组列),其值能够唯一区分表中每一个行,也可以说是表示一个特定的 行。

列作为主键的条件(规则为MYSQL本身强制实施的):

  1. 任意两行都不具有相同的主键值
  2. 每个行都必须具有主键值(不为NULL)

应该总是定义主键:要保证每个表都有一个主键,以便于以后的数据操纵与管理

主键的最好习惯:

  1. 不更新主键列中的值
  2. 不重用主键列的值;
  3. 不在主键列中使用可能会更改的值

2. 什么是SQL?

结构化查询语言(Structured Query Language), SQL是专门与数据库通信的语言。

有以下优点:

  1. 通用性,学习此语言几乎能和所有数据库进行打交道。
  2. 简单易学,它的语句全是由描述性很强的英文单词组成,且这些单词数目不多。
  3. 实用性很强,虽简单,但灵活使用该语言能进行十分复杂和高级的数据库操作。

第2章:MySQL 简介

1. 什么是MySQL

MySQL 是一种 DMBS, 数据库软件。

客户-服务器软件:
客户端用于用户进行操作,并提交请求给服务器软件,服务器软件进行过滤,丢弃和排序数据再把结果返回到客户端软件中。

一般情况下,数据库客户和服务器软件安装在一台或不同的多台计算机上。

  • 服务器软件为MySQL DBMS, 可以在本地安装的副本上运作,也可以连接在你具有访问权的远程服务器上的一个副本。
  • 客户机可以是 MySQL 提供的工具, 脚本语言,程序设计语言开发

MySQL DMBS 版本

本书将介绍 MySQL 5

2. MySQL 工具

下面我们会用客户机工具来与 MySQL 打交道

mysql 命令行实用程序
在这里插入图片描述
在本地安装后我们要输入以下命令去登录到内部:

登录时要使用 用户名,主机名,端口和口令
mysql -u username -p -h hostname -P hostpassword

完整的命令行选项和参数列表可用 mysql --help 获得

mysql 命令行程序是使用最多的程序之一,对于快速测试和执行脚本非常有价值。
请注意:

  • 命令输入在 mysql> 之后;
  • 命令用 ; 或者 \g 结束,换句话说,仅按 Enter 并不会执行命令
  • 输入 help 或者 \h 获取帮助,也可以输入更多的文本获取特定命令的帮助(如,输入 help select 获得
    使用 SELECT 语句的帮助)
  • 输入 quit 或 exit 退出命令行实用程序;

建议: 熟悉mysql命令行实用程序,因为这是唯一你可以安全依靠的捆绑安装的客户机

第3章:使用MySQL

本章将会学习如何连接和登录到 MySQL,如何执行MySQL 语句,以及如何获取到数据库和表的信息。

1. 选择数据库

使用 USE 关键字来选择数据库;

在这里插入图片描述

2. 查看数据库和表

使用 SHOW 关键字 ,后跟 DATABASES(查看数据库) 和 TABLES (查看当前选择的数据库的可用表)

在这里插入图片描述

SHOW 也可以用来显示表的列结构 (SHOW COLUMNS FROM table_name),等同于 (DESCRIBE table_name)

他对每个字段都返回一行, 【行中包含字段名,数据类型,是否NULL,键信息,默认值以及其他信息】
在这里插入图片描述
在这里插入图片描述

其他常用SHOW语句:

  1. SHOW STATUS, 用于显示广泛的服务器状态信息
  2. SHOW CREATE DATABASE 和 SHOW CREATE TABLE, 分别用于显示创建特定数据库或表的 MySQL 语句
  3. SHOW GRANTS, 用来显示授予用户(所有用户或特定用户)的安全权限
  4. SHOW ERRORS 和 SHOW WARNINGS 用来显示服务器错误或警告信息。

在这里插入图片描述

第4章:检索数据

本章将介绍如何使用 SELECT 语句从表中检索一个或多个数据列。

1. SELECT 语句

目前来说,最经常使用的 SQL 语句就是 SELECT 语句了,用途是从一个或多个表中检索信息。

为了使用 SELECT 检索表数据,需要给出两条信息: 找什么? 从什么地方找?

2. 检索单个列

命令: SELECT column_name FROM table_name;

在这里插入图片描述

注意: 如果没有明确排序查找结果,则返回的数据的顺序没有特殊意义(有可能是数据被添加到表中的顺序,也可能不是,只要返回相同数目的行,就是正常的)

3. 检索多个列

以列名分隔开即可,最后一个列不加 逗号

SELECT column1, column2, column3 FROM table_name;

在这里插入图片描述

4. 检索所有列

使用通配符 * 来返回表中所有列, 列的顺序一般是在表定义中出现的顺序,表的模式的变化(添加或删除列)可能会导致顺序的变化。

使用通配符: 一般,除非确实需要每个列才使用通配符 *,其他情况使用会降低检索和应用程序的性能。

SELECT * FROM table_name;

在这里插入图片描述

5. 检索不同的行

检索出有不同值的列表 : DISTINCT 关键字

SELECT DISTINCT column_name FROM table_name;

在这里插入图片描述

注意: 不能部分使用DISTINCT 仅应用于所有列而不仅仅是前置它的列, 除非指定的两个列都相同,否则所有行都会被检索出来。

6. 限制结果

限制最终结果的显示行数可使用: LIMIT

SELECT column1 FROM table_name LIMIT [start_line,] get_line_count

指定结果的开始行,和行数(指定行数后,是不包括开始行开始计数的), 行数不够时显示所有行

上语句在 MySQL5 等价于:

LIMIT get_line_count offset start_line

在这里插入图片描述

7. 使用完全限定的表名

SELECT table_name.column FROM table_name;
SELECT table_name.column FROM databse.table_name

第5章:排序检索数据

本章将讲授如何使用 SELECT 语句的 ORDER BY 子句, 根据需要排序检索出的数据。

1. 排序数据

如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。

子句: SQL 语句由子句构成,有些子句是必需,有些是可选的。一个子句通常由一个关键字和所提供的数据组成。

例如:SELECT 语句的 FROM子句。

为了明确地排序 SELECT 语句检索出的数据,可使用 ORDER BY 子句,ORDER BY 子句取一个或多个列的名字,据此对输出进行排序。

SELECT column_name FROM table_name ORDER BY column_name;

在这里插入图片描述

通过非选择列进行排序是完全合法的,上图最后一个语句即是演示

2. 按多个列排序

规则是:比较第一列,如果第一列不能比出顺序,则第二列。。。。。

SELECT column1, column2 FROM table_name ORDER BY column1, column2

在这里插入图片描述

3. 指定排序方向

默认排序为 ASC (ASCENDING) 升序
DESC(降序)

SELECT column1, column2 FROM table_name ORDER BY column1 DESC;

DESC 关键字只作用于位于其前面的列名。

在这里插入图片描述

第6章: 过滤数据

本章将讲授如何使用SELECT语句中的 WHERE 子句指定搜索条件

1. 使用 WHERE 子句

在SELECT语句中,数据根据 WHERE 子句指定的搜索条件进行过滤,WHERE子句在表名(FROM子句之后给出)

SELECT column1 FROM table_name WHERE condition

在这里插入图片描述

WHERE 子句的位置: 在同时使用 ORDER BY 和 WHERE 子句时,应该让 ORDER BY 位于 WHERE 之后,否则错误。
在这里插入图片描述

2. WHERE 子句操作符

WHERE 子句的条件判定,可以使用如下 MySQL 支持的所有条件操作符

操作符说明
=等于
<>不等于
!=不等于
<小于
<=小于等于
>大于
>=大于等于
BETWEEN在指定的两个值之间

注意: MySQL 执行匹配时默认不区分大小写 (字符串),且字符串值需要加 ‘’

例子1:检测单个值

在这里插入图片描述
例子2:不匹配检测

在这里插入图片描述

例子3:范围值检测

使用 BETWEEN 操作符可以在 条件中给定 两个值表示一个区间,去检测。

SELECT column1 FROM table_name WHERE column BEWEEM startvalue AND endvalue

在这里插入图片描述

4. 空值检测

不包含任何值时,称为包含空值 NULL;

NULL 无值,与字段包含 0, 空字符串和仅仅包含空格不同。

SELECT 语句使用特殊的WHERE 子句来检测 NULL 值的列。 这个 WHERE 子句就是 IS NULL 子句。

SELECT column1 FROM table_name WHERE column IS NULL;

在这里插入图片描述

注意: 在过滤选择不具有特定值的行时, 数据库并不会认为 NULL 与 他们匹配,因此在(不)匹配过滤中不会返回他们。

第7章:数据过滤

本章介绍如何组合 WHERE 子句以简历功能更强更高级的搜索条件,我们还将学习 NOT 和 IN 操作符

1. 组合 WHERE 子句

为了更强的过滤控制, MySQL 允许给出多个 WHERE 子句。这些子句可以两种方式使用: 以 AND 子句的方式或OR子句的方式使用。

操作符: 用来联结或改变 WHERE 子句中的子句的关键字, 也成为逻辑操作符。

1. AND 操作符

为了通过不止一个列进行过滤, 可以使用 AND 操作符给 WHERE 子句附加条件,并且可以添加多个过滤条件, 每添加一条就要使用一个 AND

SELECT cloumn1 FROM table_name WHERE condition1 AND condition2;

在这里插入图片描述

2. OR 操作符

OR 匹配任意条件 进行过滤, 若符合给出 WHERE 子句中的任一条件都会被筛选出来。

SELECT column1 FROM table_name WHERE condition1 OR condition2;

在这里插入图片描述

3. 计算次序

SQL 语句中 OR 操作符的优先级低于 AND 操作符,当然可以使用圆括号进行明确分组。

建议: 在 WHERE 子句中要使用圆括号明确地分组操作符,可以消除歧义,这样是最直接好阅读的。

在这里插入图片描述

2. IN 操作符

IN 操作符用来指定条件范围,范围内的每个条件都可以进行匹配。

IN 取合法值的由逗号分割的清单,全都括在圆括号中。

SELECT column1 FROM table_name WHERE column IN(val,val) 

在这里插入图片描述

IN 作用和 OR 类似:

但使用 IN 的优点如下:

  • 在使用长的合法选项清单时, IN 操作符的语法更清楚直观
  • 在使用 IN, 计算的次序更容易管理
  • IN 操作符一般比 OR 执行更快
  • IN 的最大优点是可以包含其他 SELECT 语句,使得其能够更动态地建立 WHERE 子句。

3. NOT 操作符

NOT 操作符的功能: 否定它之后所跟的任何条件。

SELECT column1, column2 FROM table_name WHERE column NOT condition

在这里插入图片描述

第8章:使用通配符进行过滤

本章将介绍什么是通配符,以及如何使用通配符以及怎样使用 LIKE 操作符进行通配搜索,以便对数据进行复杂过滤。

1. LIKE 操作符

通配符: 用来匹配值的一部分的特殊字符
搜索模式: 由字面值,通配符或两者组合构成的搜索条件。

通配符本身实际是 SQL 的 WHERE 子句中有特殊含义的字符, SQL 支持几种通配符。

为了在搜索子句中使用通配符,必须使用 LIKE 操作符。 LIKE 指示 MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。

1. 百分号(%)通配符

% 表示任何字符出现任意次数。

SELECT column1 FROM table_name WHERE column LIKE 'hand%';

在这里插入图片描述

% 通配符可以放置在 搜索模式的 任意位置,并匹配 给定位置的 0个,1个,多个字符。

注意: 空格会影响匹配,例如 ’anvil ‘ 与 ‘%anvil’ 就匹配不上。
% 似乎可以匹配任何东西,但 ‘%’ 是匹配不上 NULL 的行的

2. 下划线(_) 通配符

与%类似, _ 通配符能匹配任意字符, 但只能匹配一个字符,不能多也不能少

SELECT column1 FROM table_name WHERE column LIKE '_'

在这里插入图片描述

2. 使用通配符的技巧

MySQL 的通配符是很有用的,但这种功能是有代价的: 通配符的搜索处理相比普通搜索要更慢一点。

使用通配符的技巧:

  • 不要过度使用通配符, 如果其他操作符能达到相同目的, 应该使用其他操作符
  • 在确实需要使用通配符时, 除非绝对有必要,否则不要让他们用在搜索模式的开始处。把通配符置于搜索模式的开始处, 搜索起来是最慢的。
  • 仔细注意通配符的位置,如果放错地方,可能不会返回想要的数据。

第9章: 用正则表达式进行搜索

本章将学习如何在 MySQL WHERE 子句中内使用 正则表达式来更好的控制数据过滤。

1. 正则表达式介绍

随着过滤条件的复杂度增加, WHERE 子句的复杂性也有必要增加

这就是正则表达式有用的地方, 正则表达式是用来匹配文本的特殊的串(字符集合)
正则表达式用正则表达式语言来建立, 有必须学习的特殊语法和指令 😭 又要背东西,呜呼!!!

注意: 这里只会介绍正则表达式的基本知识, 其他完全介绍请参考其他书籍。

2. 使用 MySQL 正则表达式

MySQL 用 WHERE 子句对正则表达式提供了初步的支持,允许你指定正则表达式来过滤 SELECT 检索的数据。

注意: MySQL 仅支持多数正则表达式实现的一个很小的子集。

1. 基本字符匹配 (REGEXP)

SELECT column1 FROM table_name WHERE column REGEXP '匹配表达式'

这里 : . 是匹配单个任意字符

在这里插入图片描述

这里正则表达式匹配的结果是 ssssssss, 因为 . 这个字符会限定 ‘.ssss’ 匹配模式串中 ssss 至少要有一个 字符,这样就能过滤到一部分。
正则表达式是一种匹配子串的过程,所以若整串中有符合匹配模式的字串就会被筛选出。

LIKE 与 REGEXP:

正则表达式是一种匹配子串的过程,所以若整串中有符合匹配模式的字串就会被筛选出。而 LIKE 可以说是匹配整串的过程。

2. 进行 OR 匹配

正则表达式进行 OR 匹配的操作是使用 | 来划分

SELECT column1 FROM table_name WHERE column REGEXP 'value1|value2';

多个值即: ‘value1|value2|value3’
在这里插入图片描述

3. 匹配几个字符之一

匹配任意单一字符,但你想匹配特定的字符,可以使用 [ ] , 来替换 OR 作为另一种形式。

SELECT column1 FROM table_name WHERE column REGEXP '[valuevalue]1111';

[] 与 | 的区别是, | 并不能很好的区分匹配规则, [ ] 会限定死这个位置上的特定字符。,看如下例子

在这里插入图片描述

在这里插入图片描述

其他应用: 字符集也可以使用 ^ 进行否定,来匹配这些字符外的其他东西。

SELECT column1 FROM table_name WHERE column REGEXP '[^valuevalue]';

4. 匹配范围

为了简化 类似 [0123456789] ,我们可以使用 - 来定义一个范围 [0-9]
[a-z] 也意味着匹配任意字母字符

SELECT column1 FROM table_name WHERE  column REGEXP '[a-z]'

在这里插入图片描述

5. 匹配特殊字符

在使用特殊字符进行制作正则表达式语句时,需要加上 ‘\\’ 作为前导 , ‘\\-’ 表示查找 -

SELECT column1 FROM table_name WHERE column REGEXP '\\-';

这种处理也可以说是转义, 正则表达式内具有特殊意义的所有字符都必须以这种方式转 义。
在这里插入图片描述

元字符说明
\\f换页
\\n换行
\\r回车
\\t制表
\\v纵向制表

注意: 如果为了匹配 反斜杠 \ 自身,使用 \\
注意: 多数正则表达式实现单个反斜杠转义特殊字符, 以便能使用这些字符本身,但 MySQL 使用两个反斜杠(MySQL 自己解释一个, 正则表达式库解释另一个)


6. 匹配字符类

存在找出你自己经常使用的数字, 所有字母字符或所有数字字母字符等的匹配, 为了更方便工作,可以使用预定义的字符集,称为字符类

下面列出字符类以及它们的含义。

说明
[:alnum:]任意字母和数字 (同[a-zA-Z0-9])
[:alpha:]任意字符 (同[a-zA-Z])
[:blank:]空格和制表 (同[\\t])
[:cntrl:]ASCII 控制字符 (ASCII 0 到 31 和 127)
[:digit:]任意数字 (同[0-9])
[:graph:]与 [:print:] 相同,但不包括空格
[:lower:]任意小写字母 (同[a-z])
[:print:]任意可打印字符
[:punct:]既不在 [:alnum:] 又不在 [:cntrl:] 中的任意字符
[:space:]包括空格在内的任意空白字符(同[\\f \\n \\r \\t \\v ])
[:upper:]任意大写字母 (同[A-Z])
[:xdight:]任意十六进制数字 (同[a-fA-F0-9])

7. 匹配多个实例

单个匹配的功能有时候不能被满足需求,需要使用 更强大的 匹配重复 功能。

正则表达式用重复元字符来完成匹配多个实例。

元字符说明
*0个或多个匹配
+1个或多个匹配 {1,}
?0个或1个匹配 {0,1}
{n}指定数目的匹配
{n,}不少于指定数目的匹配
{n, m}匹配数目的范围 (m 不超过 255)

在这里插入图片描述

8. 定位符

这里我们来介绍如何匹配 特定位置的文本,如下列出的定位符

元字符说明
^文本的开始
$文本的结尾
[[:<:]]词的开始
[[:>:]]词的结尾
SELECT '1.2' REGEXP '[0-9\\.]'

我们来筛选用户名 以 不低于 4个s字符开头的,或 得字开头的用户:

在这里插入图片描述

注意:

  • ^ 的双重用途: ^ 有两种用法,在集合中(用 [和]定义),用它来否定该集合,否则用来指串的开始处。
  • 使得 REGEXP 起类似 LIKE 的作用: 使用 ^ 开始每个表达式, $ 结束

简单的正则表达式测试:

可以在不使用数据库表的情况下用 SELECT 来测试正则表达式, REGEXP 检查总是返回 0 (没有匹配) 或 1(匹配) 。可以用带文本串的 REGEXP 来测试表达式, 并试验他们。 响应的语法如下:

SELECT ‘hello’ REGEXP ‘[0-9];   

在这里插入图片描述

第10章: 创建计算字段

本章将介绍什么是计算字段, 如何创建计算字段以及怎样从应用程序中使用别名进行引用他们。

1. 计算字段

存储在数据库表中的数据一般不是 客户端 所需要的格式,虽然我们可以直接取出数据发给客户端由客户端进行加工,但是在数据库服务器上完成这些操作比在客户端机中要快得多, 因为 DBMS 是设计来快速有效地完成这种处理的。

这时对数据进行加工处理便是计算字段发挥作用的所在了。

字段: 基本上与列的意思相同, 经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。

2. 拼接字段

拼接: 将值连接到一起构成单个值

在SELECT 语句中,可以使用 Concat() 函数来拼接两个列。(多数 DBMS 使用 + )

SELECT Concat(column1, column2, val,val...) FROM table_name;

在这里插入图片描述

去除空格: 取出字符串左右的空格。

Trim() : 去除值左右两边的空格。
LTrim() : 取出值左边的所有空格。
RTrim(): 取出值右边的所有空格。

在这里插入图片描述

使用别名

上图我们可以看到,拼接后或者经过计算字段处理后 会生成新的计算列,但无名字,一个未命名的列不能用于客户机应用中,因为客户机没有办法引用它。

为了解决这个问题,SQL 支持列别名,别名仅仅是一个字段或值的替换名。 别名用 AS 关键字赋予,请看下面的 SELECT 语句:

SELECT CONCAT(TRIM(column1), column2, column3...) AS new_column FROM table_name;

在这里插入图片描述

之后就可以按照名引用到这个列进行使用。

3. 执行算术计算

可以在列之间使用 算术运算符来 获取执行算术运算后的结果

SELECT column1, column2, column1 [* - + /] column2 AS result_column FROM table_name;

在这里插入图片描述

如何测试计算: SELECT 提供了测试和试验函数与计算的一个很好的办法。

省略 FROM 子句以便简单访问和处理表达式:

在这里插入图片描述

第11章: 使用数据处理函数

本章介绍什么是函数, MySQL 支持何种函数,以及如何使用这些函数。

1. 函数

SQL 支持使用函数来处理数据, 函数一般是在数据上执行的,它给数据的转换和处理提供了方便。

注意: 函数没有 SQL 的可移植性强

多数的 SQL 语句是可移植的, 在 SQL 实现之间有差异时,这些差异通常不那么难处理,而函数的可移植性却不强。 几乎每种主要的 DBMS 的实现都支持其他实现不支持的函数,而且有时候差异还很大。

如果使用比较通用性的函数,移植性较高,但可能导致效率低下, 因此如果决定使用该函数, 应该注意保证做好代码注释,以便以后你能确切地知道所编写 SQL 代码的含义。

2. 使用函数

大多数 SQL 实现支持以下类型的函数。

  • 用于处理文本串(如删除或填充值, 转换值为大写或小写)的文本函数。
  • 用于在数值数据上进行算是操作(如返回绝对值, 进行代数运算)的数值函数。
  • 用于处理日期和时间值并从这些值中提取特定成分(例如,返回两个日期之差,检查日期有效性等)的日期和时间函数。
  • 返回 DBMS 正使用的特殊信息(如返回用户登录信息,检查版本细节)的系统函数。

1. 文本处理函数

常用的文本处理函数

函数说明
Left()返回串左边的字符
Length()返回串的长度
Locate()找出串的一个字串
Lower()将串转换为小写
LTrim()去掉串旁边的空格
Right()返回串右边的字符
RTrim()去掉串右边的空格
Soundex()返回串的 SOUNDEX 值
SubString()返回字串的字符
Upper()将串转换为大写

示例:

Upper()

SELECT Upper(column1) FROM table_name;

在这里插入图片描述
SOUNDEX() : 能对串进行发音比较而不是字母比较

SELECT column1 FROM table_name WHERE SOUNDEX(column) = '发音'

2. 日期与时间处理函数

日期和时间采用相应的数据累心和特殊的格式进行存储,以便能快速和有效的进行排序过滤,节省物理存储空间。

一般来说,应用程序并不使用存储日期和时间的格式, 因此日期和时间函数总是被用来读取,统计和处理这些值 。由于这个原因,日期和时间函数在 MySQL 函数中有重要的作用。

函数说明
AddDate()增加一个日期(天,周)
AddTime()增加一个时间(时,分)
CurDate()返回当前日期
CurTime()返回当前时间
Date()返回日期时间的日期部分
DateDiff()计算两个日期之差(天,周)
Date_Add()高度灵活的日期计算函数
Date_Format()返回一个格式化的日期或时间串
Day()返回一个日期的天数部分(天,周)
DayOfWeek()对于一个日期,返回对应的星期几(天,周)
Hour()返回一个时间的小时部分
Minute()返回一个日期的分钟部分
Month()返回一个日期的月份部分
Now()返回当前日期和时间
Second()返回一个时间的秒部分
Time()返回一个日期时间的时间部分
Year()返回一个日期的年份部分

接下来我们讲一下使用WHERE 进行过滤 时间数据时的注意点:

  • 日期格式必须为 yyyy-mm-dd ,这样能消除二义性,因为 SQL 在处理 70-99 为 1970-1999,应该总是使用4位数字的年份
  • 如果要的是日期,请使用 Date() 进行过滤掉时间部分。

如果你要的是 2020-03-21 日的信息,但 datatime 会记录日期和时间,如果这样匹配是不合理的,使用 Date 取 3-21 的部分即可。

这里我们写一个例子: 检索2005年9月下的所有订单?

SELECT cust_id FROM orders WHERE DATA(order_date) BETWEEN '2005-09-01' AND '2005-09-30';
SELECT cust_id FROM orders WHERE YEAR(order_date) = 2005 AND MONTH(order_date) = 9;

3. 数据处理函数

数据处理函数 在 DBMS 中是比较统一的。

函数说明
Abs()返回一个数的绝对值
Cos()返回一个角度的余弦
Exp()返回一个数的指数值
Mod()返回除操作的余数
Pi()返回圆周率
Rand()返回一个随机数
Sin()返回一个角度的正弦
Sqrt()返回一个数的平方根
Tan()返回一个角度的正切

第12章: 汇总数据

本章介绍什么是 SQL 的聚集函数以及如何利用它们汇总表的数据。

1. 聚集函数

对于仅需要汇总数据而不必检索出数据条目的需求, MySQL 提供了专门的函数,使用这些函数, MySQL 查询可用于检索数据, 以便分析和报表生成,例如:

  • 确定表的行数(符合条件的条有多少)
  • 获得表中行组的和
  • 找出表列(或所有行或某些特定的行)的最大值,最小值和平均值

返回实际表数据对时间和资源都是浪费,因此 使用 聚集函数就是最优解。

聚集函数: 运行在行组上,计算和返回单个值的函数。

函数说明
AVG()返回某列的平均值
COUNT()返回某列的行数
MAX()返回某列的最大值
MIN()返回某列的最小值
SUM()返回某列值之和

扩展:

标准偏差: MySQL 还支持一系列的标准偏差聚集函数。

1. AVG() 函数

作用: 通过对表中行数计数并计算特定列值之和,求得该列的平均值。
在这里插入图片描述

注意:

  • AVG 只能用于确定特定数值列的平均值,而且列名必须作为函数参数给出。
  • NULL 值 AVG 函数忽略列值为 NULL 的行。

2. COUNT() 函数

作用: 进行计数,可利用COUNT () 确定表中行的数目或符合特定条件的行的数目。

COUNT() 函数有两种计数方式:

  • 使用 COUNT(*) 对表中行的数目进行计数, 不管表中包含的空值(NULL) 还是非空值。
  • 使用 COUNT(column) 对特定列中具有值的行进行计数, 忽略 NULL 值。

在这里插入图片描述

3. MAX() 函数

MAX() 返回指定列中的最大值。 MAX() 要求指定列名

在这里插入图片描述

注意:

  • 对非数值数据使用 MAX() : 虽然 MAX() 一般用来找出最大的数或日期值, 但 MySQL 允许将它用来返回任意列的最大值,包括返回文本列中的最大值, 在用于文本数据时,如果数据按对应的列排序,则MAX返回最后一行。
  • NULL: MAX() 忽略列为 NULL 的值。

4. MIN() 函数

与 MAX 相反

5. SUM() 函数

作用: 返回指定列值的和(总计)

SELECT SUM(column1) FROM table_name WHERE column = val;

SUM 也能对多个列进行计算统计:

SELECT SUM(OPERATOR(column1, column2)) AS new_oper_column FROM table_name WHERE column = val;

NULL值: SUM() 函数忽略列值为 NULL 的行。

2. 聚集不同值

下面我们会介绍聚集函数的 DISTINCT 的使用,已经被添加到 MySQL 5 中。

以上五个聚集函数都可以如下使用:

  • 对所有的行执行计算,指定 ALL 参数或不给参数 (因为ALL是默认行为)
  • 只包含不同的值,指定 DISTINCT 参数, DISTINCT 必须指定列名。

注意: ALL 参数不需要指定,因为它是默认行为, 如果不指定 DISTINCT,则假定为 ALL。

SELECT AVG(DISTINCT column1) AS avg_price FROM table_name WHERE condition; 

在这里插入图片描述

注意:

  • DISTINCT 不能用于 COUNT(*), 只能用于指定行的 COUNT(column)

在这里插入图片描述

  • 可以使用 DISTINCT 用于 MAX() 与 MIN() , 但没什么用。

3. 组合聚集函数

其实SELECT 语句可根据需要包含多个聚集函数。

SELECT COUNT(*) AS num_items, MIN(price) AS price_min, MAX(price) AS price_max FROM table_name;

在这里插入图片描述

第13章: 分组数据

本章将介绍如何分组数据, 以便能汇总表内容的子集。这涉及两个新 SELECT 语句子句, 分别是 GROUP BY 子句和 HAVING 子句。

1. 数据分组

目前为止的所有计算都是在表的所有数据或匹配特定的 WHERE 子句的数据上进行的。

例如: 返回 一个 玩家id 为 1003 的拥有商品

SELECT COUNT(item) AS count_Item FROM item_table WHERE player_id = 1003;

但如果要返回每个玩家的拥有商品数目怎么办?

或者返回 10 个玩家所拥有的商品?

这样的需求,需要使用分组操作,分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算。

2. 创建分组

分组是在 SELECT 语句总的 GROUP BY 子句中进行建立的。

这里上述例子演示分组:

SELECT COUNT(item) AS count_item FROM item_table GROUP BY player_id;

这样就能取出 每个玩家的拥有商品数量

在具体使用GROUP BY 子句前, 需要知道一些重要的规定。

  • GROUP BY 子句可以包含任意数目的列, 这使得能对分组进行嵌套,为数据分组提供更细致的控制。
  • 如果在 GROUP BY 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(并不能从个别的列取回数据)
  • GROUP BY 子句中列出的每个列都必须是检索列或有效的表达式(不能是聚集函数)。 如果在 SELECT 中使用表达式,则必须在 GROUP BY 子句中指定相同的表达式。不能使用别名。
  • 除了聚集计算语句外, SELECT 语句中每个列都必须在 GROUP BY 的子句中给出。
  • 如果分组列中具有 NULL 值, 则 NULL 作为一个分组返回。 如果列中多个NULL,他们将被分为一组。
  • GROUP BY 子句必须出现在 WHERE 子句之后, ORDER BY 子句之前。

在这里插入图片描述

使用 ROLLUP: 使用 WITH ROLLUP 关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值,如下所示:

SELECT COUNT(column1) AS count_item FROM table_name GROUP BY column WITH ROLLUP;

在这里插入图片描述

3. 过滤分组

WHERE 过滤的是行,但如果我们想过滤分组,我们应该使用 HAVING 子句。

HAVING 支持所有 WHERE 操作符:他们的语法是相同的,只是关键字有差别。

SELECT column1, (COUNT*) FROM table_name GROUP BY column1 HAVING condition;

在这里插入图片描述

HAVING 和 WHERE 的区别:

WHERE 在分组前进行过滤, HAVING 在分组后进行过滤。因此使用 WHERE 子句过滤掉不符合的列,之后进行分组再通过 GROUP BY 进行过滤分组。

4. 分组和排序

GROUP BY 和 ORDER BY 经常完成相同的工作,但实际上他们是非常不同的。

ORDER BYGROUP BY
排序产生的输出分组行, 但输出可能不是分组的顺序
任意列都可以(非选择的列也能使用)只可能使用选择列或表达式列, 而且必须使用每个选择列表达式
不一定需要如果与聚集函数一起使用列(表达式),则必须使用

不要忘记 ORDER BY:

一般在使用 GROUP BY 子句时,应该也给出 ORDER BY 子句。这是保证数据正确排序的唯一方法。千万不要依赖 GROUP BY 子句

SELECT column1, SUM(column2 * column3) AS ordertotal FROM table_name
GROUP BY column1 HAVING SUM(column2 * column3) conditon ORDER BY ordertotal;

5. SELECT 子句顺序

SELECT 子句及其顺序

子句说明是否必须使用
SELECT要返回的列或表达式
FROM从中检索数据的表仅在从表选择数据时使用
WHERE行级过滤
GROUP BY分组说明仅在按组计算聚集时使用
HAVING组级过滤
ORDER BY输出排序顺序
LIMIT要检索的行数

第14章: 使用子查询

本章介绍什么是子查询以及如何使用它们。

1. 子查询

子查询: 嵌套在其他查询中的查询。

2. 利用子查询进行过滤

这里我们有一个 user 表存储账户信息, id, username,password ,之后 result 存放战绩, id, userid, wincount, totalcount.

我们找到 wincount > 1 的 账号 username

SELECT username FROM user WHERE id in (SELECT userid FROM result WHERE wincount > 1);

在这里插入图片描述

格式化 SQL:
包含子查询的 SELECT 语句难以阅读和调试, 特别是它们较为复杂时更是如此。 如上所示把子查询分解为多行并且适当地进行缩进,能极大地简化子查询的使用。
在这里插入图片描述

注意:

  • 子查询作为结果时应注意列的匹配
  • 子查询的性能是堪忧的。

3. 作为计算字段使用子查询

这里我们有一个 user 表存储账户信息, id, username,password ,之后 result 存放战绩, id, userid, wincount, totalcount.

我们筛选出 username,password, wincount 这种规则的数据, 会想着将id带入子查询并取得 wincount,对这就是作为计算字段使用子查询。

SELECT username,password, (SELECT wincount FROM result WHERE result.userid = user.id) 
AS wincount FROM user ORDER BY wincount;

在这里插入图片描述

涉及外部查询的子查询也叫相关子查询: 任何只要列明可能有多义性,就应该使用这种语法(表名和列名由一个句点分隔)。

总结建议:

逐渐增加子查询来建立查询:

  • 用子查询测试和调试查询很有技巧性, 特别是在这些语句的复杂度不断增加的情况下更是如此。
  • 用子查询建立(和测试)查询的最可靠的方法是逐渐进行,这与 MySQL 处理它们的方法非常相同。

首先: 建立和测试内层的查询。
然后: 用硬编码数据建立和测试外层查询,并且仅在确认它正常后才嵌入子查询。
这时:再次测试它,对于要增加的每个查询,重复这些步骤,这样仅仅给构造查询增加了一点点时间,但节省了之后对语句测试的大量时间,并且极大地提高了一开始就正常工作的可能性。

第15章: 联结表

本章将介绍什么是联结,为什么要使用 联结,如何编写使用联结的 SELECT 语句。

1. 联结

SQL 最强大的功能之一就是能在数据检索查询的执行中联结(join)表。

在能够有效地说明联结前,必须了解关系表以及关系数据库涉及的一些基础知识。

1. 关系表

一个表定义了主键, 且另一个表定义了外键,且之间相互对应,称为这两个表是关系表,且关系数据可以有效地存储和方便处理。

主键: 唯一标识一行数据的键。
外键: 包含另一个表的主键值的键。

关系表的好处可伸缩性:能够适应不断增加的工作量而不失败,设计良好的数据库或应用程序称之为 可伸缩性好。

2. 为什么要使用联结

分解数据为多个表能更有效地存储,更方便地 处理,并有更大的可伸缩性,这些好处是有代价的。

如果数据存储在多个表中,怎样用单条 SELECT 语句检索出数据?

利用联结可以使用单条 SELECT 语句检索出数据。

联结: 是一种机制,用来在一条 SELECT 语句中关联表, 因此称为联结。 使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行(联结也仅存在于查询的执行当中)。

2. 创建联结

SELECT column1, column2 FROM table1,table2 WHERE table1.id = table2.table1_id;

在这里插入图片描述

1. WHERE 子句的重要性

在联结两个表时, 你实际上做的是将第一个表中的每一行与第二个表中的每一行配对。
WHERE 子句作为过滤条件,它只包含那么匹配给定条件的(这里是联结条件的)行。

2. 内部联结

上述演示的联结为等值联结,基于两个表的相等性测试。

等值联结的其他语法:(推荐使用)

SELECT column1, column2 FROM table1 INNER JOIN table2 ON table1.id = table2.table_id;

在这里插入图片描述

3. 联结多个表

SELECT column1, column2 FROM table1,table2,table3 WHERE table1.id = table2.table1_id AND 
table2.id = table3.table2_id;

性能考虑: MySQL 在运行时关联指定的每个表以处理联结,这种处理可能是非常耗费资源的,因此应该仔细,不要联结不必要的表,联结的越多,性能下降越厉害。

第16章:创建高级联结

本章将讲解另外一些联结类型(包括它们的含义和使用方法)。介绍如何对被联结的表使用表别名和聚集函数。

1. 使用表别名

别名除了可以用于列名和计算字段外, SQL 还允许给表名起别名, 这样做的理由:

  • 缩短 SQL 语句
  • 允许在单条 SELECT 语句中多次使用相同的表。

缩短 SQL 语句的例子:

SELECT column1 FROM table_name1 AS t1, table_name2 AS t2 WHERE t1.cust_id = t2.cust_id;

在这里插入图片描述

应该注意: 表别名只在查询执行中使用, 与列别名不一样, 表别名不返回客户机。

2. 使用不同类型的联结

下面我们来讲解一下其他的三种联结: 自联结, 自然联结和外部联结。

1. 自联结

使用表别名的主要原因也是能在单条 SELECT 语句中不止一次引用相同的表。

自联结是在作为外部语句用来从相同表中检索数据。 相比子查询效率较高

例如:
SELECT p1.id, p2.name FROM table AS p1, table AS p2 WHERE p1.id = p2.id AND p2.id = 'conditon';

假若有一个产品出问题了,我们要查询到产品所属 供货商的 id,并去检索供货商的所有产品:

在这里插入图片描述

2. 自然联结

无论何时对表进行联结,应该至少有一个列出现在不止一个表中(被联结的列, 外键与主键对应,所有至少这一个列重复)

自然联结是这样一种联结: 其中你只能选择那些唯一的列,这** 一般是通过对表使用通配符(SELECT *),对其他表的列使用明确的子集完成的。

在这里插入图片描述

在这里插入图片描述

事实上,我们建立的每个内部联结都是自然联结,很可能我们永远不会用到不是自然联结的内部联结。

3. 外部联结

许多联结会将一个表的行于另一个表中的行进行相关联, 但有适合会需要关联没有关联行的那些行:

例如:

  • 对每个客户下了多数订单进行计数,包括那些至今尚未下订单的客户;

如果客户尚未下订单,这时在订单表中就无其对应记录, 但是也要进行关联,哪怕是空,这时在
联结中包含了那些在相关表中没有关联行的行。 这叫外部联结。

外联结的语法:

SELECT table1.info, tanle2.info FROM table1 LEFT/RIGHT OUTER JOIN table2 ON
connect_condition;

在这里插入图片描述

以左表为核心,使用左连接,以右边为核心,使用右脸接

注意:

  • MySQL 没有 (*= 和 =**) 这两种使用
  • 左连接和右联结的类型根据实际情况方便而定义。

3. 使用带聚集函数的联结

我们来介绍 如何 在联结中使用 聚集函数。

**加粗样式**

4. 使用联结 和 联结条件

汇总一下关于联结和使用的某些要点:

  • 注意所使用的联结类型(内部联结, 外部联结)
  • 保证使用正确的联结条件,否则将返回不正确的数据
  • 应该总是提供联结条件,否则会得出笛卡儿积
    -在一个联结中可以包含多个表, 甚至对于每个联结可以采用不同的联结类型,。虽然这样做是合法的,一般也很有效,但应该在一起测试它们前,分别测试每个联结,这将使故障排除更为简单。

第17章:组合查询

本章将介绍如何 利用 UNION 操作符将多条 SELECT 语句组合成一个结果集

1. 组合查询

MySQL 允许执行多个查询(多条 SELECT 语句),并将结果作为单个查询结果集返回。 这些组合查询通常称为 并 (union)或 复合查询。

有两种基本情况, 其中需要使用组合查询:

  • 在单个查询中从不同的表返回类似结构的数据。
  • 对单个表执行多个查询, 按单个查询返回数据。

组合查询和多个 WHERE 条件

任何具有多个 WHERE 子句的 SELECT 语句都可以作为一个组合查询给出,这两种技术在不同的查询中性能也不同。

2. 创建组合查询

利用 UNION,可给出多条 SELECT 语句,并将它们的结果组合成单个结果集合。

1. 使用 UNION

UNION 的使用规则:

SELECT column FROM table WHERE conditon UNION SELECT column2 FROM table2 WHERE condition;

我们来写一个例子:

假如需要小于等于 5 的价格的所有物品的一个列表,并且还想包括供应商 1001 和 1002 生产的物品(不考虑物品)。

在这里插入图片描述

但是你可能发现: UNION 的使用有时没有 直接用 WHERE OR 更加简单。

2. UNION 规则

正如所见, UNION 是非常容易使用的,但在进行UNION 时有几条规则需要注意:

  • UNION 必须由两条或两条以上的 SELECT 语句组成,语句之间用关键字 UNION 分割
  • UNION 中的每个查询都必须包含相同的列,表达式或聚集函数(不过各个列不需要以相同的次序列出)
  • 列数据结构必须兼容: 类型不必完全相同,但 必须是 DMBS 可以隐式地转换的类型(例如: 不同的数值类型或不同的日期类型)

3. 包含或取消重复的行

UNION 从查询结果集中自动去除了重复的行(即它的行为和 单条 SELECT 语句中使用 WHERE 子句条件一样)。

如果需要, 可以改变这种默认行为:可使用 UNION ALL 而不是 UNION, 同时 WHERE 也是完成不了这个工作的。

在这里插入图片描述

第18章:全文本搜索

第19章:插入数据

第20章:更新和删除数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值