文章目录

  • 1.了解SQL
    • 1.1.1什么是数据库
    • 1.1.2表
    • 1.1.3模式
    • 1.1.4列和数据类型
      • 数据类型
    • 1.1.5行
    • 1.1.6主键
    • 1.2什么是sql
  • 2.MySql简介
    • 2.1什么是mysql
    • 2.1.1客户机—服务器软件
    • 2.2MySql工具
    • 2.2.1MySql命令行实用程序
  • 3.使用MySql
    • 3.1连接
    • 3.2连接数据库
      • USE关键字
    • 3.3了解数据库和表
      • SHOW DATABASES关键字
      • SHOW TABLES关键字
      • SHOW COLUMNS form 表名;
      • DESCRIBE语句
      • 其他的show语句
  • 4.检索数据
    • 4.1SELECT语句
    • 检索单个列
      • 关于 ;符号
      • 关于大小写
    • 检索多列
    • 检索所有的列
      • 关于使用通配符
    • 检索去重distinct关键字
    • 限制结果Limit关键字
      • 关于行0
    • 限定表名
  • 5.排序检索数据
    • 5.1
    • 5.2子句
    • 5.3按多个列进行排序
    • 5.3指定排序方向
      • 降序
      • 升序
      • order by+limit
      • order by子句的位置
  • 6.过滤数据
    • where子句
    • 位置
    • 操作符
    • 检查单个值
    • 不匹配检查
    • 范围检查
    • 检查空值NULL
  • 7.数据过滤
    • 组合where子句
      • AND操作符
      • OR连接符
      • 计算顺序
      • 使用圆括号
    • IN操作符
      • 优点
    • NOT
      • 8.用通配符进行过滤
  • 8.百分号%通配符
    • 下划线_通配符
  • 9.正则表达式搜索
    • 作用
    • 基本字符匹配
    • . 点操作符号
    • like与 regexp
    • 进行OR匹配
    • 匹配几个字符之一
    • 匹配范围
    • 匹配特殊字符
    • 匹配字符类
    • 匹配多个实例
    • 定位符
  • 10.创建计算字段
    • 拼接字段
    • 语法
    • 分隔符
    • 值为null
    • concat_ws()
    • 使用别名 AS
    • 执行算数计算
  • 11.使用数据处理函数
    • 文本处理函数
    • 日期和时间处理函数
    • 格式
    • Date()
    • 日期区间:
    • 数值处理函数
  • 12.汇总数据
    • 聚集函数
    • AVG()函数
    • COUNT()函数
    • MAX()函数
    • MIN()函数
    • SUM()函数
    • 聚集不同值
    • 组合聚集函数
  • 13.分组数据
    • 数据分组
    • 规定
    • 过滤分组
    • 分组和排序
    • SELECT子句顺序
  • 14.使用子查询
    • 1、多表连接查询的缺点
    • 2、什么是子查询
      • (1)where子句的子查询
      • (2)from子句的子查询
  • 15.联结表
    • 外键
    • 为什么要使用联结
    • 维护引用完整性
    • 创建联结
    • 内部联结
    • 联结多个表
  • 16.高级联结
    • 使用表别名
    • 自联结
    • 自然联结
    • 外部联结
    • 使用带聚集函数的联结
    • 使用联结和联结条件
  • 17.组合查询
    • 创建组合查询
    • UNION规则
    • 包含或取消重复的行
    • 对组合查询结果排序
  • 18.全文本搜索
    • 些搜索机制的限制
    • 解决方案
    • 启用全文本搜索支持
    • 进行全文本搜索
    • 布尔文本搜索
  • 19.插入数据
    • 数据插入
    • 插入数据方法
    • 语法介绍
      • insert into
      • insert ignore into
      • replace into
  • 20.更新和删除数据
    • 更新数据
    • 组成
    • 格式
    • update的子查询
    • **UPDATE JOIN语句**
    • IGNOR
    • 删除数据
    • 格式
    • DELETE 语句的表连接(内连接)
    • DELETE 语句的表连接(外连接)
    • 更快的删除
    • MySQL 删除语句小节
  • 21.创建和操纵表
    • 创建表
    • 格式
    • 使用NULL值
    • 理解NULL
    • 主键
    • 使用AUTO_INCREMENT
    • 指定默认值
    • 引擎类型
    • 更新表
    • 删除表
    • 重命名表
  • 22.事务管理
    • 事务处理
    • 使用ROLLBACK
    • 哪些语句可以回退?
    • 使用COMMIT
    • 隐含事务关闭
    • 使用保留点
    • 更改默认的提交行为
  • 23.索引
    • 是什么
    • 存储类型
    • 索引 的优缺点
    • 索引 的分类
    • 索引的数据结构
    • 索引 的使用
  • 24.安全管理
    • 管理用户
    • 创建用户账号
    • 删除用户账号
    • 设置访问权限
    • 未来的授权
    • 简化多次授权
    • 更改口令

1.了解SQL

1.1.1什么是数据库

  1. 数据库(datebase)保存有组织的数据的容器----通常是一个文件或一组文件
  2. 数据库软件:DBMS (数据库管理系统)
    • 数据库是通过DMBS创建和操作的容器
    • 数据库是保存在硬件设备上的文件
  3. 你并不是直接访问数据库,你使用的是DBMS,它替你访问数据库

1.1.2表

  1. 表是一种结构化文件,用来存储某种特定类型的数据——某种特定类型数据的结构化清单

    • 存储在表中的数据是一种类型的数据或者一个清单
  2. 应该创建多个表,每个表都是一个清单

  3. 数据库中的每一个表都有一个名字,用来标识自己,即唯一标识

    • 数据库中没有相同名的表
  4. 表具有一些特性,它定义了数据在表中如何存储,如

    • 存储的位置
    • 存储什么样的数据
    • 数据如何分解
    • 各部分信息如何命名
    • 等等

1.1.3模式

描述表的这组信息就是所谓的模式,模式可以用来描述数据库中特点的表以及整个数据库(和表的关系)

有时,模式用作数据库的同义词

但,模式的含义通常在上下文中并不很清晰

1.1.4列和数据类型

  1. 表由列组成。列中存储表中部分信息。

  2. 列,表中的一个字段。所有表都是有一个或者多个列组成的。

  3. 每个列都有相应的数据类型,数据类型定义可以存储的数据种类(数据类型)

    • 存储的数字,则相应的数据类型为数值类型
    • 存储的日期、文本、注释、金额等,则用相应的数据类型规定出来

数据类型

  1. 数据类型是可容纳的数据的类型,每个表的列都有相应的数据类型,限制在某列中存储的数据
  2. 数据类型可存储在列中的数据种类
  3. 数据类型帮助正确的排序数据,并优化磁盘使用方面起重要作业
  4. 创建表时,必须对数据类型给与特别的关注

1.1.5行

如果将数据库的表想象成一个网格,网格中垂直的列为表列,水平行为表行

  1. 表的数据是按行进行存储的,保存的每个记录存储在自己的行内。
  2. 行和数据库记录的关系,这两个术语是可以相互替代的但是从技术上,行才是正确的术语

1.1.6主键

  1. 表中的每一行都应该有标识自己的一列(或者一组列)

  2. 主键 (primary key)一列或者一组列,它的值能区别表中每个行

  3. 唯一标识中每个行的这个列称为主键。主键用来表示一个特定的行

  4. 数据库设计人员应该保证每个表都有一个主键,为了以后数据库操作以及管理

  5. 表中任何列都可以是主键,只要满足

    • 任意两行都不具有相同的主键值
    • 每行都必须具有一个主键值(且不能为null)
  6. 主键通常定义在表的一列上,也可以使用多个列作为主键,

    • 使用多列作为主键时,上面的条件必须做到构成主键的所有列,所有列值的组合必须唯一(单列值可以不唯一)
  7. 主键的习惯

    • 不更新主键列的值
    • 不重用主键列的值
    • 不在主键列中使用会更改的值

1.2什么是sql

  1. sql:结构化查询语言(Structured Query Language)的缩写

  2. sql是专于用于与数据库通信的语言

  3. 设计sql的目的是很好的完成一项任务,即提供一种从数据库中读写数据的简单有效的方法

  4. 优点

    • 重要的DMBS都支持SQL
    • 简单易学
    • 强有力的语言,可以进行复杂和高级的数据库操作

2.MySql简介

2.1什么是mysql

MySql是一种DBMS,数据库软件

  1. Mysql开放源代码
  2. Mysql执行速度非常快
  3. 可依赖
  4. Mysql易安装与使用

2.1.1客户机—服务器软件

DMBS分为文件共享系统的DBMS和基于客户机—服务的DBMS

  1. MySql、Oracle等数据库是基友客户机—服务器的数据库

  2. 客户机—服务器分两个不同的部分

    1. 服务器部分是负责所有数据访问和处理的软件,这个软件运行在数据库服务器的计算机上
    2. 与数据文件打交道的直邮服务器软件。关于数据添加删除和更新都由服务器完成
    3. 客户机是与用户打交道的软件

2.2MySql工具

MySql是一个客户拒—服务器DBMS,为了使用MySql需要有一个客户机。

2.2.1MySql命令行实用程序

  1. 命令使用;或者\g结束
  2. 输入help或者\h获得帮助
  3. 输入quit或者exit退出命令行实用工具

3.使用MySql

3.1连接

为了连接到MySql需要

  1. 主机名(计算机名)—如果连接到本地MySql服务器,为localhost
  2. 端口(默认3306)
  3. 用户名
  4. 用户口令(密码)

3.2连接数据库

 mysql -u root -p

USE关键字

起初连接 mysql -u root -p 时没有任何数据库打开去提供使用,在执行任意数据库操作之前,需要选择一个数据库,USE

比如,为了使用aaa数据库,执行如下操作

输入:use aaa;

输出:Database changed

USE语句不返回任何结果,依赖使用的客户机显示某种形式的通知,如Database changed消息是mysql命令行实用程序选择成功后显示的

3.3了解数据库和表

一开始并不知道我有什么可以去use 去使用的数据库,则先进行如下操作

SHOW DATABASES关键字

输入SHOW DATABASES;

输出:

+--------------------+
| Database           |
+--------------------+
| aaa                |
| consumption        |
| dtcmsdb4           |
| guli               |
| information_schema |
| mall               |
| mybatis_plus       |
| mysql              |
| performance_schema |
| PhotoEdit          |
| springcloud        |
| sys                |
| test               |
+--------------------+
13 rows in set (0.00 sec)

SHOW DATABASES;返回的可用的数据库的一个列表。包含在这个列表中的可能是MySql内部使用的数据库也可能是你自己创建的数据库

SHOW TABLES关键字

为了获得数据库内的表和列表,使用SHOW TABLES;(以information_schema 为例)

输入

  1. 使用 USE

    use information_schema;
    
  2. 使用SHOW TABLES;

    show tables;
    

输出

+---------------------------------------+
| Tables_in_information_schema          |
+---------------------------------------+
| ADMINISTRABLE_ROLE_AUTHORIZATIONS     |
| APPLICABLE_ROLES                      |
| CHARACTER_SETS                        |
| CHECK_CONSTRAINTS                     |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLLATIONS                            |
| COLUMN_PRIVILEGES                     |
| COLUMN_STATISTICS                     |
| COLUMNS                               |
| COLUMNS_EXTENSIONS                    |
| ENABLED_ROLES                         |
| ENGINES                               |
| EVENTS                                |
| FILES                                 |
| INNODB_BUFFER_PAGE                    |
| INNODB_BUFFER_PAGE_LRU                |
+---------------------------------------+

SHOW TABLES;返回当前选择的数据库内可用表的列表

SHOW COLUMNS form 表名;

  1. 使用 USE

    use aaa;
    
  2. 使用SHOW TABLES;

    show tables;
    

    输出

    +---------------+
    | Tables_in_aaa |
    +---------------+
    | BookInfo      |
    | BookType      |
    | BorrowList    |
    | CardType      |
    | ReaderCard    |
    +---------------+
    5 rows in set (0.00 sec)
    
  3. 使用 SHOW COLUMNS form 表名;

    show columns from BookInfo;
    

输出

mysql> show columns from BookInfo;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| bookid       | varchar(50) | NO   | PRI | NULL    |       |
| bookname     | varchar(50) | NO   |     | NULL    |       |
| author       | varchar(50) | YES  |     | NULL    |       |
| press        | varchar(50) | YES  |     | NULL    |       |
| booklocation | varchar(50) | YES  |     | NULL    |       |
| price        | float       | YES  |     | NULL    |       |
| booktypeid   | varchar(50) | YES  | MUL | NULL    |       |
| total        | int         | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

SHOW COLUMNS要求给一个表名(例子中的from BookInfo),会对每个字段返回一行,行中包括字段名、数据类型、是否允许NULL、键信息、默认值以及其他信息

什么是自动增量

一些表列需要唯一值,例如订单编号、聘员id或者顾客id。在每个行添加到表中时,MySql会自动为每个行自动地为每个行分配下一个可用编号,不用在添加下一行的时候手动分配唯一值——自动增量

DESCRIBE语句

DESCRIBE BookInfo; = show columns from BookInfo;

MySql支持用DESCRIBE来作为 show columns from的一种快捷方式

其他的show语句

  1. show status用于显示服务器的状态信息
  2. show create databaseshow create table分别用于显示创建特定的数据库或者表的MySql语句
  3. show grants 用于显示授权用户(所有用户或者特定用户)的安全权限
  4. show errorsshow warnings用于显示服务器错误或者警告消息

4.检索数据

4.1SELECT语句

为了使用select语句必须至少给出两条信息—想选择什么,以及从什么地方选择

检索单个列

格式:

SELECT 想选择什么
FROM 从什么地方选择;

输入:

SELECT bookname
from BookInfo;

输出

+-----------------------+
| bookname              |
+-----------------------+
| 电脑乐园              |
| Java2核心技术         |
| 计算机应用基础        |
| 大学语文教程          |
| 谁动了我的奶酪        |
| 倾城之恋              |
| 盗墓笔记              |
| 韩寒作品集            |
| 沉睡之城111           |
| 爱丽丝漫游奇境        |
+-----------------------+
10 rows in set (0.00 sec)

分析:

上述语句使用SELECT语句从BookInfo表中检索一个名为bookname的列,将表中指定列全部返回。

关于 ;符号

结束SQL语句就是;,多条SQL语句必须以分号;分割。

关于大小写

SQL语句不区分大小写,SELECT=select=Select

规范:对SQL关键字使用大写,对列和表名使用小写。

检索多列

上述只是检索了bookname一列下面展示检索多列

想从一个表中检索多列,使用相同的SELECT语句。唯一不同的是必须在SELECT关键字后给出多个需要检索的列名,列名直接必须一逗号分割,最后一列不可以添加逗号。

格式:

SELECT 想选择1,想选择2,想选择3
FROM 从什么地方选择;

输入:

SELECT bookname,bookid,author
from BookInfo;

输出

+-----------------------+-----------+------------------+
| bookname              | bookid    | author           |
+-----------------------+-----------+------------------+
| 电脑乐园              | 1008-2352 | 谭宇             |
| Java2核心技术         | 7111-1790 | Gray Comel       |
| 计算机应用基础        | 7305-0458 | 黄强             |
| 大学语文教程          | 7564-1018 | 董自厚           |
| 谁动了我的奶酪        | 7800-7336 | 斯宾塞.约翰      |
| 倾城之恋              | 7800-8287 | 莫然             |
| 盗墓笔记              | 9787-5057 | 南派三叔         |
| 韩寒作品集            | 9787-5378 | 韩寒             |
| 沉睡之城111           | 9787-5613 | 蔡骏             |
| 爱丽丝漫游奇境        | 9787-8020 | 卡罗尔           |
+-----------------------+-----------+------------------+
10 rows in set (0.00 sec)

检索所有的列

除了指定列之外,SELECT语句还可以通过通配符星号*来检索所有列

格式:

SELECT *
FROM 从什么地方选择;

输入:

SELECT *
from BookInfo;

输出

+-----------+-----------------------+------------------+-----------------------------+--------------+-------+------------+-------+
| bookid    | bookname              | author           | press                       | booklocation | price | booktypeid | total |
+-----------+-----------------------+------------------+-----------------------------+--------------+-------+------------+-------+
| 1008-2352 | 电脑乐园              | 谭宇             | 广西电脑乐园杂志社          | TP3/K29      |    52 | T          |    30 |
| 7111-1790 | Java2核心技术         | Gray Comel       | 机械工业出版社              | TP312/233    |    68 | T          |     5 |
| 7305-0458 | 计算机应用基础        | 黄强             | 南京大学出版社              | TP3/913      |  27.4 | T          |    15 |
| 7564-1018 | 大学语文教程          | 董自厚           | 东南大学出版社              | H1/56        |    34 | H          |    20 |
| 7800-7336 | 谁动了我的奶酪        | 斯宾塞.约翰      | 中信出版社                  | B825/49      |  23.5 | B          |    10 |
| 7800-8287 | 倾城之恋              | 莫然             | 华凌出版社                  | I247/566     |  30.5 | I          |    20 |
| 9787-5057 | 盗墓笔记              | 南派三叔         | 中国友谊出版公司            | I247/468     |    28 | I          |    20 |
| 9787-5378 | 韩寒作品集            | 韩寒             | 北岳文艺出版社              | I217/257     |    36 | I          |    40 |
| 9787-5613 | 沉睡之城111           | 蔡骏             | 陕西师范大学出版社          | I247/66      |    25 | I          |    10 |
| 9787-8020 | 爱丽丝漫游奇境        | 卡罗尔           | 光明日报出版社              | I561/18      |  26.3 | I          |    12 |
+-----------+-----------------------+------------------+-----------------------------+--------------+-------+------------+-------+
10 rows in set (0.00 sec)

如果给定一个通配符*号,则返回表中所有列,列的顺序是列在表中定义的顺序

关于使用通配符

一般最好不要使用通配符*号,虽然使用通配符可能会使自己省事省力,不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。

检索去重distinct关键字

一般SELECT会返回所有匹配的行,但是,如果你不想要每个值每次都出现这时候需要用到distance。

如:

mysql> select press from BookInfo;
+-----------------------------+
| press                       |
+-----------------------------+
| 广西电脑乐园杂志社          |
| 机械工业出版社              |
| 南京大学出版社              |
| 东南大学出版社              |
| 南京大学出版社              |
| 南京大学出版社              |
| 南京大学出版社              |
| 南京大学出版社              |
| 南京大学出版社              |
| 南京大学出版社              |
+-----------------------------+
10 rows in set (0.00 sec)

select语句返回10行,其中大量重复,使用distance解决。

输入:

 SELECT DISTINCT  press from BookInfo;

输出

+-----------------------------+
| press                       |
+-----------------------------+
| 广西电脑乐园杂志社          |
| 机械工业出版社              |
| 南京大学出版社              |
| 东南大学出版社              |
+-----------------------------+
4 rows in set (0.00 sec)

分析 SELECT DISTINCT press 告诉mysql之封你号不同的press行,因此只返回4行,如果使用distanct语句, 必须放在列名的最前面,一旦使用distinct则应用的是所有的列。

限制结果Limit关键字

select语句返回所有匹配的行,他们可能是表中的每个行,为了只返回前几行数据,可使用limit字句。

输入:

select press
from BookInfo
LIMIT 5;

输出

+-----------------------------+
| press                       |
+-----------------------------+
| 广西电脑乐园杂志社          |
| 机械工业出版社              |
| 南京大学出版社              |
| 东南大学出版社              |
| 南京大学出版社              |
+-----------------------------+
5 rows in set (0.00 sec)

分析:

使用LIMIT 5 指示MySQL返回不多于5行

为了得到下一个5行,可指定要检索的开始行与行数

输入:

select press
from BookInfo
LIMIT 5,5;

输出

+-----------------------+
| press                 |
+-----------------------+
| 南京大学出版社        |
| 南京大学出版社        |
| 南京大学出版社        |
| 南京大学出版社        |
| 南京大学出版社        |
+-----------------------+
5 rows in set (0.00 sec)

分析:

LIMIT 5,5返回从第五行开始的5行。第一个数字为开始位置,第二个为要检索的行数

关于行0

检索出来的第一行为行0即下标从0开始计算,因此,LIMIT 1,1 将检索出第二行而不是第一行。

限定表名

如果,列prod_name在表products中,则可以

输入:

SELECT products.prod_name
FROM  products;

如果,列prod_name在表products中,且表products在crashcourse数据库中则可以

输入:

SELECT products.prod_name
FROM  crashcourse.products;

5.排序检索数据

本章讲select语句的order by 字句

5.1

检索出的数据并不是以纯粹的随机显示的,如果不排序,数据将以它在底层出现的顺序排序。如果数据后面进行过更新或者删除,可能会受到MySql重用回收存储空间的影响。关系型数据库设计理论任务,如果不明确规定排序,则不应该假定检索出的数据的顺序有意义

5.2子句

  1. SQL语句由子句构成,有的是必须的有的是可选的。一个句子通常由一个关键字和所提供的数据组成。子句例子有SELECT语句的FROM子句

  2. 为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。

    • 可使用ORDER BY子句取一个或者多个列的名字,据此对输出进行排序

输入:

select bookid
from BookInfo;

输出:

+-----------+
| bookid    |
+-----------+
| 7800-7336 |
| 7564-1018 |
| 7800-8287 |
| 9787-5057 |
| 9787-5378 |
| 9787-5613 |
| 9787-8020 |
| 1008-2352 |
| 7111-1790 |
| 7305-0458 |
+-----------+
10 rows in set (0.00 sec)

输入:

select bookid
from BookInfo
order by bookid;

输出:

+-----------+
| bookid    |
+-----------+
| 1008-2352 |
| 7111-1790 |
| 7305-0458 |
| 7564-1018 |
| 7800-7336 |
| 7800-8287 |
| 9787-5057 |
| 9787-5378 |
| 9787-5613 |
| 9787-8020 |
+-----------+
10 rows in set (0.00 sec)

这条语句除了指示MySql对bookid列以顺序排序数据的order by子句外,与前面的语句相同

通常,使用order by子句中使用的列将是为显示所选择的列,但是并非一定需要这样。

5.3按多个列进行排序

为了按多个列排序,只需要指定列名,列名直接使用逗号分开即可

下面的语句先按书名排序 再按作者排序

输入

 select bookid,bookname,author from BookInfo order by bookname,author;

输出

+-----------+-----------------------+------------------+
| bookid    | bookname              | author           |
+-----------+-----------------------+------------------+
| 7111-1790 | Java2核心技术         | Gray Comel       |
| 7800-8287 | 倾城之恋              | 莫然             |
| 7564-1018 | 大学语文教程          | 董自厚           |
| 9787-5613 | 沉睡之城111           | 蔡骏             |
| 9787-8020 | 爱丽丝漫游奇境        | 卡罗尔           |
| 1008-2352 | 电脑乐园              | 谭宇             |
| 9787-5057 | 盗墓笔记              | 南派三叔         |
| 7305-0458 | 计算机应用基础        | 黄强             |
| 7800-7336 | 谁动了我的奶酪        | 斯宾塞.约翰      |
| 9787-5378 | 韩寒作品集            | 韩寒             |
+-----------+-----------------------+------------------+
10 rows in set (0.00 sec)

多个排序时,完全安装规定的顺序进行排序,对于上面的例子输出中,如果bookname列有相同的,则按author对相同的bookname进行排序。

5.3指定排序方向

降序

通过降序排序,必须指定DESC关键字

格式

select 列名
from 表名
order by 列名 DESC;

下面例子按照价格降序

select *
from products
order by prod_price desc;

如果使用降序的时候打算用多个列排序则使用逗号分割开(最贵的在前面)

select *
from products
order by prod_price desc,prod_name;

分析:DESC 关键字只应用到直接位于其前面的列名,因此上列中不会对prod_name进行降序排序

注意:如果你想要也prod_name也同时进行降序则必须参考如下

select *
from products
order by prod_price desc,prod_name desc;

分析:对每个列都指定DESC关键字

升序

与desc关键字想反的是ASC,在升序排序的时候指定,默认是升序的格式与使用desc一致

order by+limit

使用order by+和limit组合,找出一个列中最高或者最低的值:

select *
from products
order by prod_price desc
limit 1;

order by子句的位置

在给出order by 子句时,应该保证位于from子句后,如果使用limit,必须位于order bv之后。

6.过滤数据

本章讲授SELECT语句的WHERE语句指定搜索条件

where子句

通常只会根据特定操作或者报告的需要提取表数据的子集,只检索需要的数据需要指定搜索条件,搜索条件也称为过滤条件

在select语句中,数据根据where子句搜索指定条件进行过滤where子句在表名(from子句)之后给出

输入:

select bookname
from BookInfo
where bookname = '电脑乐园';

输出:

+--------------+
| bookname     |
+--------------+
| 电脑乐园     |
+--------------+
1 row in set (0.00 sec)

分析:

这条语句会从BookInfo 表中检索一个列,只根据where子句中指定的搜索条件进行过滤,返回bookname是电脑乐园的行

位置

在同时使用order by和where子句时,应该让order by位于where子句之后

操作符

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

检查单个值

输入:

select bookid,booknamefrom bookInfowhere bookname= 'javA2核心技术';

输出:

+-----------+-------------------+
| bookid    | bookname          |
+-----------+-------------------+
| 7111-1790 | Java2核心技术     |
+-----------+-------------------+
1 row in set (0.00 sec)

检查 where bookname= 'javA2核心技术’语句,他返回bookname值为javA2核心技术的一行。mysql默认不区分大小写所以 javA2核心技术与Java2核心技术匹配

检查价格小于等于52元的所有产品

输入:

select bookid , bookname,price
from bookInfo
where price <=52;

输出:

+-----------+-----------------------+-------+
| bookid    | bookname              | price |
+-----------+-----------------------+-------+
| 1008-2352 | 电脑乐园              |    52 |
| 7305-0458 | 计算机应用基础        |  27.4 |
| 7564-1018 | 大学语文教程          |    34 |
| 7800-7336 | 谁动了我的奶酪        |  23.5 |
| 7800-8287 | 倾城之恋              |  30.5 |
| 9787-5057 | 盗墓笔记              |    28 |
| 9787-5378 | 韩寒作品集            |    36 |
| 9787-5613 | 沉睡之城111           |    25 |
| 9787-8020 | 爱丽丝漫游奇境        |  26.3 |
+-----------+-----------------------+-------+
9 rows in set (0.00 sec)

不匹配检查

查出press不是南京大学出版社的所有产品

select bookid,press
from BookInfo
where press<> '南京大学出版社';

或者:

select bookid,press
from BookInfo
where press!= '南京大学出版社';

输出

+-----------+-----------------------------+
| bookid    | press                       |
+-----------+-----------------------------+
| 1008-2352 | 广西电脑乐园杂志社          |
| 7111-1790 | 机械工业出版社              |
| 7564-1018 | 东南大学出版社              |
+-----------+-----------------------------+
3 rows in set (0.00 sec)

范围检查

为获得某个范围的值,可使用BETWEEN操作符使用and连接进行分割,需要指定开始值与结束值,查出价格5-30元之间的产品

输入

select bookid , bookname,price
from bookInfo
where price between 5 and 30;

输出

+-----------+-----------------------+-------+
| bookid    | bookname              | price |
+-----------+-----------------------+-------+
| 7305-0458 | 计算机应用基础        |  27.4 |
| 7800-7336 | 谁动了我的奶酪        |  23.5 |
| 9787-5057 | 盗墓笔记              |    28 |
| 9787-5613 | 沉睡之城111           |    25 |
| 9787-8020 | 爱丽丝漫游奇境        |  26.3 |
+-----------+-----------------------+-------+
5 rows in set (0.00 sec)

检查空值NULL

返回指定列是空的行(不是0也不是空格)

语句

select bookid , bookname,price
from bookInfo
where price  IS NULL;

7.数据过滤

本章节讲 组合where子句,NOT和IN操作符

组合where子句

mysql中允许给出多个where子句,以and子句的方式或者or子句方式使用

AND操作符

为了通过多个列一起进行过滤,可使用and操作符给where子句附加条件

输入:

select bookid,press,price
from BookInfo
where press= '南京大学出版社' and price <=30;

输出:

+-----------+-----------------------+-------+
| bookid    | press                 | price |
+-----------+-----------------------+-------+
| 7305-0458 | 南京大学出版社        |  27.4 |
| 7800-7336 | 南京大学出版社        |  23.5 |
| 9787-5057 | 南京大学出版社        |    28 |
| 9787-5613 | 南京大学出版社        |    25 |
| 9787-8020 | 南京大学出版社        |  26.3 |
+-----------+-----------------------+-------+
5 rows in set (0.00 sec)

分析:

此sql中查出出版社是南京大学出版社并且价格小于等于30的行。

这条select语句中where包含两个条件,并用and连接他们。

AND指示DBMS只返回满足所有条件的行。

注意:每多加一个条件就要多使用一个AND进行连接

OR连接符

OR连接符指示mysql检索匹配任意条件的行(匹配多少个条件返回多少个条件的结果的行)

输入:

select bookid,press,price
from BookInfo
where press= '南京大学出版社'and price <=35  or
press= '东南大学出版社 ' and price <=35;

输出:

+-----------+-----------------------+-------+
| bookid    | press                 | price |
+-----------+-----------------------+-------+
| 7305-0458 | 南京大学出版社        |  27.4 |
| 7564-1018 | 东南大学出版社        |    34 |
| 7800-7336 | 南京大学出版社        |  23.5 |
| 7800-8287 | 南京大学出版社        |  30.5 |
| 9787-5057 | 南京大学出版社        |    28 |
| 9787-5613 | 南京大学出版社        |    25 |
| 9787-8020 | 南京大学出版社        |  26.3 |
+-----------+-----------------------+-------+
7 rows in set (0.00 sec)

OR告诉DBMS匹配任意一条件的而不是同时匹配所有条件

计算顺序

如果将上面的改成

select bookid,press,price
from BookInfo
where press= '南京大学出版社' or press= '东南大学出版社 ' and price <=35;

我们理解的结果是他们返回 南京大学出版社的或者东南大学出版社的且返回的价格小于等于35元。

实际上输出:

+-----------+-----------------------+-------+
| bookid    | press                 | price |
+-----------+-----------------------+-------+
| 7305-0458 | 南京大学出版社        |  27.4 |
| 7564-1018 | 东南大学出版社        |    34 |
| 7800-7336 | 南京大学出版社        |  23.5 |
| 7800-8287 | 南京大学出版社        |  30.5 |
| 9787-5057 | 南京大学出版社        |    28 |
| 9787-5378 | 南京大学出版社        |    36 |
| 9787-5613 | 南京大学出版社        |    25 |
| 9787-8020 | 南京大学出版社        |  26.3 |
+-----------+-----------------------+-------+
8 rows in set (0.00 sec)

注意:| 9787-5378 | 南京大学出版社 | 36 |

多了一条不符合我们预测的数据,这里涉及到计算顺序问题

and的计算次序高于or的计算次序,优先操作的是or,

所以SQL执行的是查出东南大学出版社的并且价格大于35元的 或者查出所有南京大学出版社的

解决方法:使用()明确的分组相应的操作符

select bookid,press,price
from BookInfo
where (press= '南京大学出版社' or press= '东南大学出版社 ') and price <=35;

输出:

+-----------+-----------------------+-------+
| bookid    | press                 | price |
+-----------+-----------------------+-------+
| 7305-0458 | 南京大学出版社        |  27.4 |
| 7564-1018 | 东南大学出版社        |    34 |
| 7800-7336 | 南京大学出版社        |  23.5 |
| 7800-8287 | 南京大学出版社        |  30.5 |
| 9787-5057 | 南京大学出版社        |    28 |
| 9787-5613 | 南京大学出版社        |    25 |
| 9787-8020 | 南京大学出版社        |  26.3 |
+-----------+-----------------------+-------+
7 rows in set (0.00 sec)

分析:圆括号()具有比and或or操作符更高的计算次序,dbms会先过滤()内的or条件

使用圆括号

任何时候使用具有and或者or操作符的where子句,都应该使用圆括号明确的分组操作符,他能消除歧义。

IN操作符

IN操作符指定条件范围,范围中的每个条件都可以进行匹配。IN里面的值用逗号进行分割,全括在圆括号中。

输入:

select bookid,press,price
from BookInfo
where press in ('南京大学出版社','东南大学出版社 ');

输出:

+-----------+-----------------------+-------+
| bookid    | press                 | price |
+-----------+-----------------------+-------+
| 7305-0458 | 南京大学出版社        |  27.4 |
| 7564-1018 | 东南大学出版社        |    34 |
| 7800-7336 | 南京大学出版社        |  23.5 |
| 7800-8287 | 南京大学出版社        |  30.5 |
| 9787-5057 | 南京大学出版社        |    28 |
| 9787-5378 | 南京大学出版社        |    36 |
| 9787-5613 | 南京大学出版社        |    25 |
| 9787-8020 | 南京大学出版社        |  26.3 |
+-----------+-----------------------+-------+
8 rows in set (0.01 sec)

分析:检索出出版社为东南大学出版社和南京大学的所有产品

IN的功能和or是一致的

优点

  1. 语法清晰直观
  2. 次序易管理
  3. In的执行速度比or快
  4. 可以包含其他select语句,更快捷动态建立where语句

NOT

Where子句中的not操作符 有且只有一个功能,否定他之后所跟的任何条件

语句:

select bookid,press,price
from BookInfo
where press NOT in ('南京大学出版社','东南大学出版社 ');

输出:

+-----------+-----------------------------+-------+
| bookid    | press                       | price |
+-----------+-----------------------------+-------+
| 1008-2352 | 广西电脑乐园杂志社          |    52 |
| 7111-1790 | 机械工业出版社              |    68 |
+-----------+-----------------------------+-------+
2 rows in set (0.00 sec)

8.用通配符进行过滤

本章讲什么是通配符,如何使用通配符,以及怎样使用like操作符

LIKE操作符:进行模糊查询查询包含了xx的字符的列

8.百分号%通配符

最常用的通配符就是百分号%,在搜索串中,%表示任何字符出现任意次数。例如找出以java开头的产品

输入:

select bookid,bookname
from bookinfo
where bookname like 'java%';

输出:

+-----------+-------------------+
| bookid    | bookname          |
+-----------+-------------------+
| 7111-1790 | Java2核心技术     |
+-----------+-------------------+
1 row in set (0.00 sec)

分析:检索任意以java开头的词 %告诉MySql接收java之后任意的词,不管多少

使用多个通配符:

输入:

select bookid,bookname,press
from bookinfo
where press like '%大学%';

输出:

+-----------+-----------------------+-----------------------+
| bookid    | bookname              | press                 |
+-----------+-----------------------+-----------------------+
| 7305-0458 | 计算机应用基础        | 南京大学出版社        |
| 7564-1018 | 大学语文教程          | 东南大学出版社        |
| 7800-7336 | 谁动了我的奶酪        | 南京大学出版社        |
| 7800-8287 | 倾城之恋              | 南京大学出版社        |
| 9787-5057 | 盗墓笔记              | 南京大学出版社        |
| 9787-5378 | 韩寒作品集            | 南京大学出版社        |
| 9787-5613 | 沉睡之城111           | 南京大学出版社        |
| 9787-8020 | 爱丽丝漫游奇境        | 南京大学出版社        |
+-----------+-----------------------+-----------------------+
8 rows in set (0.00 sec)

通配符可在搜索模式中任意位置使用,并且使用多个,上面的使用了两个并位于模式的两端

搜索模式%大学%表示匹配任意位置包含文本大学的值,不论他的前后出现了上面字符

搜索a开头b结尾的字符

select bookid,bookname,press
from bookinfo
where press like 'a%b';

下划线_通配符

下划线_用%用途基本一致,但下划线匹配单个字符而不是多个字符

再重申一遍%,%表示任何字符出现任意次数(多个字符)

再复述一遍_,_表示任何字符出现单个(单个字符)

9.正则表达式搜索

作用

匹配文本,将一个模式(正则表达式)与一个文本串进行比较。MySQL

用WHERE子句对正则表达式提供了初步的支持,允许你指定正则表达式,

过滤SELECT检索出的数据

基本字符匹配

检索列bookname包含文本java的所有行:

输入:

select bookname
from bookinfo
where bookname REGEXP 'java';

输出:

+--------------+
| bookname     |
+--------------+
| Java2核心技? |
+--------------+
1 row in set (0.53 sec)

分析:

关键字LIKE被REGEXP替代外,这条语句看上去非常像使用 LIKE的语句

它告诉MySQL:REGEXP后所跟的东西作为正则表达式

(与文字正文java匹配的一个正则表达式)处理

. 点操作符号

输入:

select bookname
from bookinfo
where bookname REGEXP '.111';

输出:

+------------+
| bookname   |
+------------+
| ?睡之城111 |
+------------+
1 row in set (0.00 sec)

分析:

这里使用了正则表达式.111

.是正则表达式语言中一个特殊的字符

它表示匹配任意一个字符,因此, ?睡之城111 都匹配且返回

like与 regexp

LIKE匹配整个列。如果被匹配的文本在列值 中出现,LIKE将不会找到它,相应的行也不被返回(除非使用 通配符)。

而REGEXP在列值内进行匹配,如果被匹配的文本在 列值中出现,REGEXP将会找到它,相应的行将被返回

进行OR匹配

为搜索两个串之一(或者为这个串,或者为另一个串),使用|

输入

 select bookname from bookinfo where bookname REGEXP 'java|111';

输出

+--------------+
| bookname     |
+--------------+
| Java2核心技? |
| ?睡之城111   |
+--------------+
2 rows in set (0.04 sec)

分析

使用|从功能上类似于在SELECT语句中使用OR语句

多个OR条件可并入单个正则表达式

匹配几个字符之一

想匹配特定的字符使用 [和]

如: [123]b ,这里使用了正则表达式,[123]定义一组字符,1b或者2b或者3b都会返回

输入

select bookname from bookinfo where bookname REGEXP '[123] b'

输出

+--------------+
| bookname     |
+--------------+
| 1b           |
| 2b           |
+--------------+
2 rows in set (0.04 sec)

分析:

[]是另一种形式的OR语句

正则表达式[123]Ton 为[1|2|3]Ton的缩写,也可以使用后者

但是,需要用[]来定义OR语句查找什么

匹配范围

匹配数字0到9:

[0123456789]

可以简化为[0-9]

如[0-9]a

匹配特殊字符

为了匹配特殊字符,必须用\为前导。\-表示查找-,\.表示查找.

一些其他意思:

  • \f 换页
  • \n 换行
  • \r 回车
  • \t 制表
  • \v 纵向制表

匹配字符类

[: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])

[:xdigit:] 任意十六进制数字(同[a-fA-F0-9])

匹配多个实例

  • 0个或多个匹配

  • 1个或多个匹配(等于{1,})

  • ? 0个或1个匹配(等于{0,1})

  • {n} 指定数目的匹配

  • {n,} 不少于指定数目的匹配

  • {n,m} 匹配数目的范围(m不超过255)

正则表达式\([0-9] sticks?\)

\(匹配), [0-9]匹配任意数字(这个例子中为1和5)

sticks?匹配stick 和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出 现),\)匹配)

没有?,匹配stick和sticks会非常困难

[:digit:]匹配任意数字,因而它为数字的一个集 合。{4}确切地要求它前面的字符(任意数字)出现4次,所以 [[:digit:]]{4}匹配连在一起的任意4位数字

定位符

为了匹配特定位置的文本如下:

^ 文本的开始

$ 文本的结尾

[[:<:]] 词的开始

[[:>:]] 词的结尾

找出以一个数(包括以小数点开始的数)开始的所有产品

1

匹配串的开始。因此,[0-9\.]只在.或任意数字为串中第1个字符时才匹配它们。

没有^,则还要多检索出4个别的行(那些中间有数字的行)

  • **^**的双重用途

    • ^有两种用法。在集合中(用[和]定义),用它 来否定该集合,否则,用来指串的开始处。
    • 使REGEXP起类似LIKE的作用 本章前面说过,LIKE和REGEXP 的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位 符,通过用^开始每个表达式,用$结束每个表达式,可以使 REGEXP的作用与LIKE一样。

10.创建计算字段

拼接字段

  • 拼接(concatenate) 将值联结到一起构成单个值
  • 把两个列拼接起来。在MySQL的SELECT语句中,可使用 Concat()函数来拼接两个列
  • 多数DBMS使用+或||来实现拼接, MySQL则使用Concat()函数来实现

将多个字符串连接成一个字符串

输入:

 select Concat(bookname,'(',author,')') from bookinfo;

输出:

 select Concat(bookname,'(',author,')') from bookinfo;

分析:

Concat()拼接串,即把多个串连接起来形成一个较长的串。

Concat()需要一个或多个指定的串,各个串之间用逗号分隔

上面的SELECT语句连接以下4个元素

  • 存储bookname列中的名字
  • 包含一个空格和一个左圆括号的串;
  • 存储在author列中的作者
  • 包含一个右圆括号的串

语法

concat(str1, str2,…) 返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null

演示:

select concat (id, name) as info from t1;

分隔符

例2:在例1的结果中三个字段id,name,score的组合没有分隔符,我们可以加一个逗号作为分隔符:

select concat (id,‘,’ ,name) as info from t1;

值为null

如果其中一个值为null , 则最终合并的值也为null

concat_ws()

\1. 含义:

和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)

\2. 语法:

concat_ws(separator, str1, str2, …)

说明:第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。

3、举例:

例3:我们使用concat_ws()将 分隔符指定为逗号,达到与例2相同的效果:

select concat_ws(‘,’,id ,name) as info from t1;

±------±-----------------------+
| info
±------±-----------------------+
| 10001,沙 |
| 10001,石 |
| 10001,煤 |
| 10002,水 |
| 10002,盐 |
| 10002,盐 |
| 10002,盐2 |
±------±-----------------------+
例4:把分隔符指定为null,结果全部变成了null:

±------±-----------------------+
| info
±------±-----------------------+
| null |
| null |
| null |
| null |
| null |
| null |
| null |
±------±-----------------------+

使用别名 AS

SELECT语句拼接地址字段工作得很好

但是新计算列没有名字

别名用AS关键字赋予

输入

 select Concat(bookname,'(',Rtrim(author),')') AS cloumNewName from bookinfo;

输出

+--------------------------+
| cloumNewName             |
+--------------------------+
| ????(?宇)                |
| Java2核心技?(Gray Comel) |
| ?算机?用基?(黄?)         |
| 大学?文教程(董自厚)      |
| ??了我的?酪(斯?塞.?翰)   |
| ?城之恋(莫然)            |
| 盗墓??(南派三叔)         |
| ?寒作品集(?寒)           |
| ?睡之城111(蔡?)          |
| ???漫游奇境(???)         |
+--------------------------+
10 rows in set (0.00 sec)

分析:

  • SELECT语句本身与以前使用的相同,只不过这里的语句中计算 字段之后跟了文本AS cloumNewName。
  • 它指示SQL创建一个包含 指定计算的名为cloumNewName的计算字段

执行算数计算

select 列1, 列2, 列3 * 列4 AS 列5

11.使用数据处理函数

文本处理函数

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

日期和时间处理函数

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

格式

MySql不管是插入或更新表值还是用WHERE子句进行过滤

日期格式必须为 yyyy-mm-dd

Date()

在where查询日期的时候必须使用Date() 函数

Date(order_date)指示MySQL仅提取列的日期部分

尽量使用:

select *
from orders
where Date(order)='2005-09-01'

避免使用:

select *
from orders
where order='2005-09-01'

日期区间:

日期区间使用between and

select *
from orders
where Date(order) between'2005-09-01' and '2005-09-10'

分析:

BETWEEN操作符用来把2005-09-01和2005-09-10定义为 一个要匹配的日期范围。

一种不需要记住每个月中有多少天或不需要操心闰年2月的办法

select *
from orders
where Year(order) between'2005' and Month(order) =9

Year()是一个从日期(或日期时间中返回年份的函数

Month()从日期中返回月份

Month()从日期中返回月份检索出order_date为2005年9月的 所有行

补充:

以下示例返回2018-01-15的当天的日期:

mysql> SELECT DAY('2018-01-15');
+-------------------+
| DAY('2018-01-15') |
+-------------------+
|                15 |
+-------------------+
1 row in set

要根据指定的日期获取一个月中的天数,您可以组合LAST_DAY和DAY函数,如以下示例所示:

mysql> SELECT DAY(LAST_DAY('2018-02-03'));
+-----------------------------+
| DAY(LAST_DAY('2018-02-03')) |
+----------------------------
|                          28 |
+-----------------------------+
1 row in set

LAST_DAY函数返回一月的最后一天,例如2016-02-29,DAY函数返回最后一天的那个月的日期,也就是该月份的天数。

数值处理函数

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

12.汇总数据

聚集函数

聚集函数(aggregatefunction) 运在行组上,计算和返回单个值的函数

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

AVG()函数

AVG()通过对表中行数计数并计算特定列值之和,求得该列的平均值

 select AVG(price) AS avg_price
From bookinfo;

输出

+--------------------+
| avg_price          |
+--------------------+
| 35.069999885559085 |
+--------------------+

AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值

 select AVG(price) AS avg_price
From bookinfo
where bookid in('1008-2352','7111-1790');

输出

+-----------+
| avg_price |
+-----------+
|        60 |
+-----------+

COUNT()函数

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

COUNT()函数有两种使用方式

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

MAX()函数

  • MAX()返回指定列中的最大值。MAX()要求指定列名
  • NULL值MAX()函数忽略列值为NULL的行

对非数值数据使用MAX() 虽然MAX()一般用来找出最大的 数值或日期值

但MySQL允许将它用来返回任意列中的最大值,包括返回文本列中的最大值

在用于文本数据时,如果数据按相应的列排序,则MAX()返回最后一行

MIN()函数

  • MIN()返回指定列的最小值与 MAX()一样,MIN()要求指定列名
  • NULL值MIN()函数忽略列值为NULL的行

对非数值数据使用MIN() MySQL允许将它用来返回任意列中的最小值包括返回文本列中的最小值

在用于文本数据时,如果数据按相应的列排序,则MIN()返回最前面的行

SUM()函数

  • SUM()用来返回指定列值的和(总计)
  • SUM()也可以用来合计计算值
  • NULL值SUM()函数忽略列值为NULL的行

聚集不同值

组合聚集函数

13.分组数据

数据分组

分组在SELECT语句的GROUP BY子句中建立

输入

 select press ,count(*)  As datefrom bookinfogroup by press;

输出

+----------------+------+
| press          | date |
+----------------+------+
| 广西?????志社  |    1 |
| 机械工?出版社  |    1 |
| 南京大学出版社 |    7 |
| ?南大学出版社  |    1 |
+----------------+------+
4 rows in set (0.02 sec)

date为计算字段(用COUNT(*)函数建立)

GROUP BY子句指 示MySQL按press排序并分组数据

这导致对每个pressd而不是整个表计算date一次从输出中可以看到

广西???志社有1个产品

机械工?出版社有1个产品

南京大学出版社有7个产品

?南大学出版社 有1个产品。

规定

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

过滤分组

  • 规定包括哪些分组,排除哪些分组,必须基于完整的分组而不是个别的行进行过滤

  • WHERE过滤指定的是行而不是分组,WHERE没有分组的概念

  • HAVING非常类似于WHERE

    • 目前为止所 学过的所有类型的WHERE子句都可以用HAVING来替代
      唯一的差别是 WHERE过滤行,而HAVING过滤分组
  • HAVING支持所有WHERE操作符

输入

select press ,count(*)  As date
from bookinfo
group by press
having count(*)>=2;

输出

+----------------+------+
| press          | date |
+----------------+------+
| 南京大学出版社 |    7 |
+----------------+------+
1 row in set (0.01 sec)

它过滤COUNT(*) >=2(两个以上的订单)的那些分组

分组和排序

ORDER BY

排序产生的输出任意列都可以使用(甚至非选择的列也可以使用)

不一定需要

GROUP BY

分组行。但输出可能不是分组的顺序只可能使用选择列或表达式列,而且必须使用每个选择 列表达式

如果与聚集函数一起使用列(或表达式),则必须使用

SELECT子句顺序

SELECT 要返回的列或表达式

FROM 从中检索数据的表 仅在从表选择数据时使用

WHERE 行级过滤

GROUP BY 分组说明 仅在按组计算聚集时使用

HAVING 组级过滤

ORDER BY 输出排序顺序

LIMIT 要检索的行数

14.使用子查询

1、多表连接查询的缺点

多表连接查询的缺点:先进行两个表的笛卡尔积,然后再查询符合条件的记录。性能很差。通常用子查询代替多表连接查询

2、什么是子查询

什么是子查询:在一个select语句的from子句或where子句中包含另一个select语句。通常把外层的select语句称为主查询,把内层的select语句称为子查询

在数据库xy中创建一张表,命名为 dept

CREATE TABLE `xy`.`dept` (`deptno` INT NOT NULL,`dname` VARCHAR(45) NULL,`dphone` VARCHAR(11) NULL,PRIMARY KEY (`deptno`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_bin;INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('10', '开发部', '02978956543');
INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('60', '市场部', '01012345678');
INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('30', '设计部', '01078956458');
INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('40', '采购部', '01056897458');
INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('50', '总经办', '01066458978');

(1)where子句的子查询

where子句的子查询:即在where子句中嵌套select语句。将子查询返回的值作为主查询的查询条件。

eg1:查询部门编号小于’设计部’的员工信息

-- 查询部门编号小于'设计部'的员工信息,where子句中的子查询,子查询返回值的是主查询的条件
select * from emp
where deptno < (select deptno from dept where dname='设计部' -- 子查询,查询'设计部'的部门编号);

eg2:查询部门编号小于’设计部’并且薪水大于1500的员工信息

-- 查询部门编号小于'设计部'并且薪水大于1500的员工信息
select * from emp
where deptno <(select deptno from dept where dname = '设计部') and sal > 1500;

eg3:同表中的子查询,查询与姓名WARD的job、sal相同的员工信息

-- 同表中的子查询,查询与姓名WARD的job、sal相同的员工信息
select * from emp
where (job,sal) = (  -- 在emp表中找到和员工WARD的job、sal 相同的员工信息select job,sal from empwhere ename = 'WARD'   -- 子查询,在emp表中找到员工WARD的job、sal);

eg4:查询emp表中的部门编号在deptn部门表中的员工信息

-- 在子查询中使用in、not in-- 查询emp表中的部门编号在deptn部门表中的员工信息select * from emp  where deptno in (select deptno from dept -- 先查询dept表中所有的部门编号)

(2)from子句的子查询

from子句的子查询:内嵌的select语句返回的是一个临时表,然后再从这个临时表中查询符合条件的记录。该方式可以用于实现多表连接查询。

给dept表中添加新的一行

INSERT INTO `xy`.`dept` (`deptno`, `dname`, `dphone`) VALUES ('20', '监察部', '02948985689');

eg:查询员工所在的部门编号、部门名称、员工人数和平均工资

-- from子句中的子查询
-- 查询员工所在的部门编号、部门名称、员工人数和平均工资
select d.deptno,dname,counts,avge -- 将dept里所查询得到的部门编号、员工人数和平均工资作为一个表命名为d
from dept as d inner join(  -- 建立内连接,连接d表和e表select deptno,count(empno) as counts,avg(sal) as avgefrom empgroup by deptno  -- 子查询。查询三个部门的部门编号、员工人数以及每个部门的平均工资) as e -- 将子查询所得到的表命名为e
on d.deptno = e.deptno;

15.联结表

外键

外键(foreign key)外键为某个表中的一列,它包含另一个表 的主键值,定义了两个表之间的关系

  • 这样做的好处如下:

    1. 供应商信息不重复,从而不浪费时间和空间;
    2. 如果供应商信息变动,可以只更新vendors表中的单个记录
    3. 相关表中的数据不用改动;
    4. 由于数据无重复,显然数据是一致的,这使得处理数据更简单。

总之,关系数据可以有效地存储和方便地处理
因此,关系数据库的可伸缩性远比非关系数据库要好

可伸缩性(scale)能够适应不断增加的工作量而不失败
设 计良好的数据库或应用程序称之为可伸缩性好

为什么要使用联结

分解数据为多个表能更有效地存储,更方便地处理,并 且具有更大的可伸缩性

联结是一种机制,用来在一条SELECT 语句中关联表,因此称之为联结
使用特殊的语法,可以联结多个表返 回一组输出,联结在运行时关联表中正确的行

维护引用完整性

重要的是,要理解联结不是物理实体,它在实际的数据库表中不存在
联结由MySQL根据需 要建立,它存在于查询的执行当中。

在使用关系表时,仅在关系列中插入合法的数据非常重要
如果在products表中插入拥有非法供应商ID (即没有在vendors表中出现)
的供应商生产的产品,则这些 产品是不可访问的因为它们没有关联到某个供应商

为防止这种情况发生,可指示MySQL只允许在products表的

供应商ID列中出现合法值(即出现在vendors表中的供应商)。

这就是维护引用完整性,它是通过在表的定义中指定主键和外

键来实现的

创建联结

格式:

select 列1,列2,列3
from 表1,表2
where 表1.列=表2.列

输入:

select vend_name,prod_name,prod_price
from vendors,products
where vendors.vend_id=products.vend_id

分析:

  1. 最大的差别是所指定的两个列(prod_name 和prod_price)在一个表中,而另一个列(vend_name)在另一个表中的FROM
  2. 子句列出了两个表,分别是vendors和products。它们就是这条SELECT 语句联结的两个表的名字
  3. 这两个表用WHERE子句正确联结,WHERE子句 指示MySQL匹配vendors表中的vend_id和products表中的vend_id
  4. WHERE子句作为 过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行

内部联结

目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的 相等测试。这种联结也称为内部联结

可以写成:

select 列1,列2,列3
from 表1 inner join 表2
on 表1.列=表2.列

输入:

select vend_name,prod_name,prod_price
from vendors inner join products
on vendors.vend_id=products.vend_id

联结多个表

QL对一条SELECT语句中可以联结的表的数目没有限制。创建联结

的基本规则也相同。首先列出所有表,然后定义表之间的关系

性能考虑

MySQL在运行时关联指定的每个表以处理联结。

这种处理可能是非常耗费资源的,因此应该仔细,不要联结

不必要的表。联结的表越多,性能下降越厉害

16.高级联结

使用表别名

SQL还允许给表名起别名。这样做有两个主要理由

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

格式:

select 别名.列1, 别名.列2
from 表1 AS 别名
where 别名.id=条件

输入:

select c.id, c.name
from custom AS c
where c.id= 1

自联结

案例:

你发现某物品(其ID为DTNTR)存在问题,因此想知道生产该物品的供应商生产的其他物品是否也存在这些问题。此查询要求首先找到 生产ID为DTNTR的物品的供应商,然后找出这个供应商生产的其他物品

输入

select prod_id,prod_name
from products
where vend_id=(select vend_idfrom productswhere prod_id='DTNTR');

分析:使用子查询,对内部进行检索返回生产的id为DTNTR物品供应商的vend_id

使用联结查询完成

select p1.prod_id,p1.prod_name
from products as p1,products as p2
where p1.vend_id =p2.vend_id
And p2.prod_id='DTNTR';

分析:

此查询中需要的两个表实际上是相同的表
products表在FROM子句中出现了两次
products的第一次出现为别名p1,第二次出现为别名p2
WHERE(通过匹配p1中 的vend_id和p2中的vend_id)
首先联结两个表,然后按第二个表中的 prod_id过滤数据,返回所需的数据

用自联结而不用子查询

自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。虽然最终的结果是相同的,但有时候处理联结远比处理子查询快得多

自然联结

外部联结

许多联结将一个表中的行与另一个表中的行相关联。但有时候会需要包含没有关联行的那些行。例如,可能需要使用联结来完成以下工作

  • 对每个客户下了多少订单进行计数,包括那些至今尚未下订单的客户;
  • 列出所有产品以及订购数量,包括没有人订购的产品;
  • 计算平均销售规模,包括那些至今尚未下订单的客户。

联结包含了那些在相关表中没有关联行的行,这种类型的联结称为外部联结

检索所有客户的订单,包括那些没有订单的客户

输入:

select c.cust_id, o.order_num
from customer as c left outer join orders as o
on c.cust_id =o.cust_id

使用了关键字OUTER JOIN来指定联结的类型

与内部联结关联两个表中的行不同的是,外部联结还包括没有关联行的行

使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)

使用带聚集函数的联结

聚集函数用来汇总数据。虽然至今为止聚集函数的所有例子只是从单个表汇总数据,但这些函数也可以与联结一起使用

使用联结和联结条件

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

17.组合查询

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

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

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

组合查询和多个WHERE条件

多数情况下,组合相同表的两个查询完成的工作与具有多个WHERE子句条件的单条查询完成的工作相同。换句话说,任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询给出

这两种技术在不同的查询中性能也不同。因此,应该试一下这

两种技术,以确定对特定的查询哪一种性能更好

创建组合查询

用UNION操作符来组合数条SQL查询,用UNION,可给出多条SELECT语句,将它们的结果组合成单个结果集

创建UNION涉及编写多条SELECT语句。首先来看单条语句

输入

 select bookid,bookname,author
from bookinfo
where price <30;

输出

+-----------+-------------+-----------+
| bookid    | bookname    | author    |
+-----------+-------------+-----------+
| 7305-0458 | ?算机?用基? | 黄?       |
| 7800-7336 | ??了我的?酪 | 斯?塞.?翰 |
| 9787-5057 | 盗墓??      | 南派三叔  |
| 9787-5613 | ?睡之城111  | 蔡?       |
| 9787-8020 | ???漫游奇境 | ???       |
+-----------+-------------+-----------+
5 rows in set (0.00 sec)

输入

select bookid,bookname,author
from bookinfo
where press ='南京大学出版社';

输出

+-----------+-------------+-----------+
| bookid    | bookname    | author    |
+-----------+-------------+-----------+
| 7305-0458 | ?算机?用基? | 黄?       |
| 7800-7336 | ??了我的?酪 | 斯?塞.?翰 |
| 7800-8287 | ?城之恋     | 莫然      |
| 9787-5057 | 盗墓??      | 南派三叔  |
| 9787-5378 | ?寒作品集   | ?寒       |
| 9787-5613 | ?睡之城111  | 蔡?       |
| 9787-8020 | ???漫游奇境 | ???       |
+-----------+-------------+-----------+
7 rows in set (0.00 sec)

为了组合这两条语句,使用union

输入

 select bookid,bookname,author
from bookinfo
where price <30
union
select bookid,bookname,author
from bookinfo
where press='南京大学出版社';

输出

+-----------+-------------+-----------+
| bookid    | bookname    | author    |
+-----------+-------------+-----------+
| 7305-0458 | ?算机?用基? | 黄?       |
| 7800-7336 | ??了我的?酪 | 斯?塞.?翰 |
| 9787-5057 | 盗墓??      | 南派三叔  |
| 9787-5613 | ?睡之城111  | 蔡?       |
| 9787-8020 | ???漫游奇境 | ???       |
| 7800-8287 | ?城之恋     | 莫然      |
| 9787-5378 | ?寒作品集   | ?寒       |
+-----------+-------------+-----------+
7 rows in set (0.12 sec)

这条语句由前面的两条SELECT语句组成,语句中用UNION关键字分隔
UNION指示MySQL执行两条SELECT语句,并把输出组合成单个查询结果集

使用多条WHERE子句:

输入

 select bookid,bookname,author
from bookinfo
where price <30
or press='南京大学出版社';

输出

+-----------+-------------+-----------+
| bookid    | bookname    | author    |
+-----------+-------------+-----------+
| 7305-0458 | ?算机?用基? | 黄?       |
| 7800-7336 | ??了我的?酪 | 斯?塞.?翰 |
| 7800-8287 | ?城之恋     | 莫然      |
| 9787-5057 | 盗墓??      | 南派三叔  |
| 9787-5378 | ?寒作品集   | ?寒       |
| 9787-5613 | ?睡之城111  | 蔡?       |
| 9787-8020 | ???漫游奇境 | ???       |
+-----------+-------------+-----------+
7 rows in set (0.00 sec)

在这个简单的例子中,使用UNION可能比使用WHERE子句更为复杂

但对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据

的情形,使用UNION可能会使处理更简单

UNION规则

  1. UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个 UNION关键字)
  2. UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)
  3.  列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)

包含或取消重复的行

  • UNION从查询结果集中自动去除了重复的行(换句话说,它的行为与单条SELECT语句中使用多个WHERE子句条件一样)
  • 这是UNION的默认行为,但是如果需要,可以改变它。事实上,如果想返回所有匹配行,可使用UNION ALL而不是UNION

对组合查询结果排序

在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。对于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一部分的情况,因此不允许使用多条ORDER BY子句

 select bookid,bookname,author
from bookinfo
where price <30
union
select bookid,bookname,author
from bookinfo
where press='南京大学出版社'
order by bookname;

这条UNION在最后一条SELECT语句后使用了ORDER BY子句。虽然ORDER BY子句似乎只是最后一条SELECT语句的组成部分,但实际上MySQL将用它来排序所有SELECT语句返回的所有结果

使用UNION的组合查询可以应用不同的表

18.全文本搜索

些搜索机制的限制

  1. 性能——通配符和正则表达式匹配通常要求MySQL尝试匹配表中所有行(而且这些搜索极少使用表索引)。因此,由于被搜索行数不断增加,这些搜索可能非常耗时
  2. 明确控制——使用通配符和正则表达式匹配,很难(而且并不总是能)明确地控制匹配什么和不匹配什么。例如,指定一个词必须匹配,一个词必须不匹配,而一个词仅在第一个词确实匹配的情况下才可以匹配或者才可以不匹配。
  3. 智能化的结果——虽然基于通配符和正则表达式的搜索提供了非常灵活的搜索,但它们都不能提供一种智能化的选择结果的方法。例如,一个特殊词的搜索将会返回包含该词的所有行,而不区分包含单个匹配的行和包含多个匹配的行(按照可能是更好的匹配来排列它们)。类似,一个特殊词的搜索将不会找出不包含该词但包含其他相关词的行

解决方案

所有这些限制以及更多的限制都可以用全文本搜索来解决。在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样,MySQL可以快速有效地决定哪些词匹配(哪些行包含它们),哪些词不匹配,它们匹配的频率,等等

启用全文本搜索支持

一般在创建表时启用全文本搜索

FULLTEXT子句(见21)

create table productnotes(note_id int not null auto_incerment,prod_id char(10) not null,note_date datetime  not null,note_text text  null,primary key(note_id),FullText(note_text)
)Enging=MyISAM;

MySQL根据子句FULLTEXT(note_text)的指示对它进行索引。这里的FULLTEXT索引单个列,如果需要也可以指定多个列

  • 在定义之后,MySQL自动维护该索引。在增加、更新或删除行时,索引随之自动更新

可以在创建表时指定FULLTEXT,或者在稍后指定(在这种情况下所有已有数据必须立即索引)

  • 不要在导入数据时使用FULLTEXT

进行全文本搜索

在索引之后,使用两个函数Match()和Against()执行全文本搜索,

其中Match()指定被搜索的列,Against()指定要使用的搜索表达式

select note_text
from productnotes
where Math(note_text) Against('rabit');

此SELECT语句检索单个列note_text。由于WHERE子句,一个全

文本搜索被执行。Match(note_text)指示MySQL针对指定的

列进行搜索,Against(‘rabbit’)指定词rabbit作为搜索文本。由于有

两行包含词rabbit,这两个行被返回

使用完整的 Match() 说 明 传递给 Match() 的值必须与FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)

搜索不区分大小写

刚才的搜索可以简单地用LIKE子句完成

select note_text
from productnotes
where note_text Like '%rabbit%'

排序

select note_text
from productnotes
where Math(note_text) Against('rabit') AS rank;
  • Match()和Against() 用来建立一个计算列(别名为rank),此列包含全文本搜索计算出的等级值
  • 等级由MySQL根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来

布尔文本搜索

19.插入数据

数据插入

INSERT

  1. 插入完整的行
  2. 插入行的一部分
  3. 插入多行
  4. 插入某些查询的结果

没有输出INSERT语句一般不会产生输出

插入数据方法

mysql中常用的三种插入数据的语句:

  • insert into:正常的插入数据,插入数据的时候会检查主键或者唯一索引,如果出现重复就会报错;
  • replace into:表示插入并替换数据,若表中有primary key或者unique索引,在插入数据的时候,若遇到重复的数据,则用新数据替换,如果没有数据效果则和insert into一样;
  • insert ignore into:插入并忽略数据,如果中已经存在相同的记录,则忽略当前新数据。这样不用校验是否存在了,有则忽略,无则添

语法介绍

insert into

每个字段与其值是严格一一对应的。也就是说:每个值、值的顺序、值的类型必须与对应的字段相匹配。但是,各字段也无须与其在表中定义的顺序一致,它们只要与 VALUES中值的顺序一致即可。

语法如下:

# 表中有些字段有默认值,则可以直接根据字段插入数据
INSERT INTO 表名(字段名1,字段名2,...) VALUES (值 1,值 2,...);# 按照表中所有字段进行插入数据,一定要与字段在表中定义的顺序一致
INSERT INTO 表名 VALUES (值 1,值 2,...);

insert ignore into

这种方式的语法跟insert into 是一样的,只不过在遇到重复的数据时做出的处理不一致,有重复的就忽略该条数据的插入

语法如下:

# 表中有些字段有默认值,则可以直接根据字段插入数据
INSERT IGNORE INTO 表名(字段名1,字段名2,...) VALUES (值 1,值 2,...);# 按照表中所有字段进行插入数据,一定要与字段在表中定义的顺序一致
INSERT IGNORE INTO 表名 VALUES (值 1,值 2,...);

MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,对于插入数据时候遇到重复的primary key 时候,可以进行数据的更新,就避免了insert ignore into遇到重复的数据直接忽略的不足。但是一定要保证使用的时候是想要更新重复数据哦,不然就尴尬啦~~

replace into

REPLACE INTO study VALUES(1 , 'a' , 11);
REPLACE INTO study VALUES(9 , 'i' , 18);

20.更新和删除数据

更新数据

为了更新(修改)表中的数据,可使用UPDATE语句。可采用两种方

式使用UPDATE

  1. 更新表中特定行
  2. 更新表中所有行

组成

UPDATE语句由3部分组成

  1. 要更新的表
  2. 列名和它们的新值
  3. 确定要更新行的过滤条件

格式

UPDATE <表名> SET 字段1=值1 [,字段2=值2…]
[WHERE子句]
[ORDER BY子句]
[LIMIT子句]
  • <表名>:指定需要更新的表名称;
  • SET子句:指定表中要修改的列名及其列值。每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字DEFAULT表示列值。修改一行数据的多个列值时,SET 子句的每个值用逗号分开即可;
  • WHERE子句:可选项。用于限定表中要修改的行;若不指定,则会修改表中所有的行;
  • ORDER BY子句:可选项。用于限定表中的行被修改的次序;
  • LIMIT子句:可选项。用于限定被修改的行数。

update的子查询

在UPDATE语句中使用子查询UPDATE语句中可以使用子查询UPDATE语句中可以使用子查询,使得能用SELECT语句检索出的数据更新列数据

UPDATE JOIN语句

两个表,wangfalin和area,通过id进行连接,同时更改wangfalin表里面NAME为wangfalin为王发林,area表里面area为四川省德阳市中江县

UPDATE wangfalin
LEFT JOIN area
ON wangfalin.id=area.id
SET area.area = "四川省德阳市中江县",wangfalin.NAME="王发林"
WHERE wangfalin.id=101

IGNOR

IGNORE关键字如果用UPDATE语句更新多行,并且在更新这些行中的一行或多行时出一个现错误,则整个UPDATE操作被取消(错误发生前更新的所有行被恢复到它们原来的值)。为即使是发生错误,也继续进行更新,可使用IGNORE关键字

删除数据

为了从一个表中删除(去掉)数据,使用DELETE语句。可以两种方式使用DELETE

  1. 从表中删除特定的行
  2. 从表中删除所有行

删除表的内容而不是表DELETE语句从表中删除行,甚至是删除表中所有行。但是,DELETE不删除表本身

格式

DELETE [IGNORE] FROM 表名
WHERE 条件1, 条件2, .....
ORDER BY ......
LIMIT ......;

– 使用 IGNORE 关键字时,当存在外键约束组织我们删除记录,那么则会忽略删除该条数据

– 使用 WHERE 子句删除条件范围内的记录;如果不使用 WHERE 子句,则是删除全表范围

– 使用 ORDER BY 关键字,将被删除的记录进行排序以后,产出符合条件的一些数据

– 使用 LIMIT 关键字依然是分页的意思,

DELETE 语句的表连接(内连接)

DELETE 表1, ...... FROM 表1 JOIN 表2 ON 条件
WHERE 条件1, 条件2, ......
ORDER BY ......
LIMIT ......

“WHERE”、“ORDER BY”、“LIMIT” 子句都是可选条件

DELETE 语句的表连接(外连接)

DELETE 表1, ...... FROM 表1 [LEFT | RIGHT] JOIN 表2 ON 条件
WHERE 条件1, 条件2, ......
ORDER BY ......
LIMIT ......

“WHERE”、“ORDER BY”、“LIMIT” 子句都是可选条件

– 除了 在连接表 的时候选择 “LEFT JOIN” 与 “RIGHT JOIN” 的区别之外,其他的与内连接的语法一样

更快的删除

如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快(TRUNCATE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)

TRUNCATE TABLE 表名;

“TRUNCATE” 语句一次只能清空一张数据表,不能够一次性的清空多张数据表。

MySQL 删除语句小节

语句 功能
drop 语句 删除数据库和表 drop 数据库名; drop 表名;
delete 语句 删除表中的记录 delete from weibo_user where username=“xiaomu”; 注意:delete语句中如果没有加入where条件,将会把表中的所有记录全部删除
update set 语句 修改和更新语句,更新时也会覆盖(删除)原来的值 update set与where搭配使用,变更某些记录 注意::update set语句中如果没有where子句指定其变更的条件,将就会把数据库中这个字段的所有值都更新
alert 语句 删除字段:alter table 表名 drop 字段名; 删除主键:alter table 表名 drop primary key ; 更新表名:alter table 表名 rename to 新表名;

21.创建和操纵表

创建表

MySQL不仅用于表数据操纵,而且还可以用来执行数据库和表的所

有操作,包括表本身的创建和处理。

一般有两种创建表的方法:

  1. 使用具有交互式创建和管理表的工具
  2. 表也可以直接用MySQL语句操纵

使用SQL的CREATE TABLE语句

格式

cerate table 表名 [IF NOT EXISTS]
列名  类型 not null,
列名  类型 null,
primary key (列名)
)Enging=InnDB;
  • 首先,指定要在CREATE TABLE子句之后创建的表的名称
    表名在数据库中必须是唯一的
    IF NOT EXISTS是语句的可选部分,允许检查正在创建的表是否已存在于数据库中如果是这种情况,MySQL将忽略整个语句,不会创建任何新的表
    强烈建议在每个CREATE TABLE语句中使用IF NOT EXISTS来防止创建已存在的新表而产生错误。
  • 其次,每列的定义以列名(它在表中必须是唯一的)开始
    表的主键可以在创建表时用PRIMARY KEY关键字指定
    整条语句由右圆括号后的分号结束
  • 后跟列的数据类型
    字段的列用逗号(,)分隔
  • 第三,需要为engine子句中的表指定存储引擎MySQL将默认使用InnoDB

使用NULL值

每个表列或者是NULL列,或者是NOT NULL列,这种状态在创建时由表的定义规定

cerate table 表名
列名  类型 not null,
列名  类型 null,
primary key (列名)
)Enging=InnDB;

理解NULL

NULL值是没有值,它不是空串。如果指定’'(两个单引号,其间没有字符),这在NOT NULL列中是允许的。空串是一个有效的值,它不是无值。NULL值用关键字NULL而不是空串指定

主键

  • 主键值必须唯一
  • 表中的每个行必须具有唯一的主键值
  • 如果使用多个列,则这些列的组合值必须唯一
  • 主键可以在创建表时定义

使用AUTO_INCREMENT

  • AUTO_INCREMENT告诉MySQL,本列每当增加一行时自动增量
  • 每次执行一个INSERT操作时,MySQL自动对该列增量(从而才有这个关键字AUTO_INCREMENT),给该列赋予下一个可用的值
  • 给每个行分配一个唯一的id,从而可以用作主键值
  • 每个表只允许一个AUTO_INCREMENT列,而且它必须被索引(如,通过使它成为主键)

指定默认值

如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。
默认值用CREATE TABLE语句的列定义中的DEFAULT关键字指定。

cerate table 表名
列名  类型 not null,
列名  类型 null,
列名  类型 null, default 1,
primary key (列名)
)Enging=InnDB;

述添加文本DEFAULT 1指示MySQL,在未给出数量的情况下使用数量1

使用默认值而不是NULL值 许多数据库开发人员使用默认值而不是NULL列,特别是对用于计算或数据分组的列更是如此

引擎类型

  1. InnoDB是一个可靠的事务处理引擎(参见第26章),它不支持全文本搜索;
  2. MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘) 中,速度很快(特别适合于临时表);
  3. MyISAM是一个性能极高的引擎,它支持全文本搜索(参见第18章),但不支持事务处理

更新表

为更新表定义,可使用ALTER TABLE语句。但是,理想状态下,当表中存储数据以后,该表就不应该再被更新

为了使用ALTER TABLE更改表结构,必须给出下面的信息

  1. 在ALTER TABLE之后给出要更改的表名(该表必须存在,否则将出错);
  2. 所做更改的列表

删除表

删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可

drop table 表名

删除 表(假设它存在)。删除表没有确认,也不能撤销,执行这条语句将永久删除该表

重命名表

使用RENAME TABLE语句可以重命名一个表

Rename table 旧表名 TO 新表名

22.事务管理

事务处理

  1. 事务(transaction)指一组SQL语句;
  2. 回退(rollback)指撤销指定SQL语句的过程;
  3. 提交(commit)指将未存储的SQL语句结果写入数据库表;
  4. 保留点(savepoint)指事务处理中设置的临时占位符(placeholder),你可以对它发布回退(与回退整个事务处理不同)

使用ROLLBACK

MySQL的ROLLBACK命令用来回退(撤销)MySQL语句

哪些语句可以回退?

事务处理用来管理INSERT、UPDATE和 DELETE语句。你不能回退SELECT语句。(这样做也没有什么意义。)你不能回退CREATE或DROP操作。事务处理块中可以使用这两条语句,但如果你执行回退,它们不会被撤销

使用COMMIT

一般的MySQL语句都是直接针对数据库表执行和编写的。这就是所谓的隐含提交(implicit commit),即提交(写或保存)操作是自动进行的。但是,在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句

隐含事务关闭

当COMMIT或ROLLBACK语句执行后,事务会自动关闭(将来的更改会隐含提交)

使用保留点

简单的ROLLBACK和COMMIT语句就可以写入或撤销整个事务处理
但是,只是对简单的事务处理才能这样做,更复杂的事务处理可能需要部分提交或回退
描述添加订单的过程为一个事务处理。如果发生错误,只需要返回到添加orders行之前即可,不需要回退到customers表(如果存在的话)
为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符
这样,如果需要回退,可以回退到某个占位符
这些占位符称为保留点。为了创建占位符,可如下使用SAVEPOINT语句

savepoint 保留点名

每个保留点都取标识它的唯一名字,以便在回退时,MySQL知道要回退到何处。为了回退到本例给出的保留点

rollback to 保留点名

保留点越多越好——保留点越多,你就越能按自己的意愿灵活地进行回退

释放保留点保留点在事务处理完成(执行一条ROLLBACK或COMMIT)后自动释放

更改默认的提交行为

  • 默认的MySQL行为是自动提交所有更改
  • 任何时候你执行一条MySQL语句,该语句实际上都是针对表执行的,而且所做的更改立即生效
  • 为指示MySQL不自动提交更改,需要使用以下语句
    set autocommit =0

autocommit标志决定是否自动提交更改,不管有没有COMMIT语句。设置autocommit为0(假)指示MySQL不自动提交更改(直到autocommit被设置为真为止)

23.索引

是什么

索引是一个单独的、存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针

存储类型

MySQL中索引的存储类型有两种,即 BTree 和 Hash

索引 的优缺点

优点:

  • 提高数据的查询的效率(类似于书的目录)

  • 可以保证数据库表中每一行数据的唯一性(唯一索引)

  • 减少分组和排序的时间(使用分组和排序子句进行数据查询)

    • 被索引的列会自动进行分组和排序

缺点:

  • 占用磁盘空间
  • 降低更新表的效率(不仅要更新表中的数据,还要更新相对应的索引文件)

索引 的分类

1、普通索引 和 唯一索引

  • 普通索引:MySQL 中的基本索引类型,允许在定义索引的列中插入 重复值 和 空值

  • 唯一索引:要求索引列的值必须 唯一,但允许 有空值

    • 如果是组合索引,则列值的组合必须 唯一
    • 主键索引是一种特殊的唯一索引,不允许 有空值

2、单列索引 和 组合索引

  • 单列索引:一个索引只包含单个列,一个表可以有多个单列索引

  • 组合索引:在表的 多个字段 组合上 创建的 索引

    • 只有在查询条件中使用了这些字段的 左边字段 时,索引才会被使用(最左前缀原则)

3、全文索引

  • 全文索引 的类型为 fulltext
  • 在定义索引的 列上 支持值的全文查找,允许在这些索引列中插入 重复值 和 空值
  • 全文索引 可以在 char、varchar 和 text 类型的 列 上创建

4、空间索引

  • 空间索引 是对 空间数据类型 的字段 建立的索引
  • MySQL中的空间数据类型有4种,分别是 Geometry、Point、Linestring 和 Polygon
  • MySQL 使用 Spatial 关键字进行扩展,使得能够用创建正规索引类似的语法创建空间索引
  • 创建空间索引的列,不允许为空值,且只能在 MyISAM 的表中创建。

5、前缀索引

  • 在 char、varchar 和 text 类型的 列 上创建索引时,可以指定索引 列的长度

索引的数据结构

MySQL 索引 的数据结构可以分为 BTree 和 Hash 两种,BTree 又可分为 BTree 和 B+Tree

Hash:使用 Hash 表存储数据,Key 存储索引列,Value 存储行记录或行磁盘地址。

Hash 只支持等值查询(“=”,“IN”,“<=>”),不支持任何范围查询(原因在于 Hash 的每个键之间没有任何的联系),Hash 的查询效率很高,时间复杂度为 O(1)。

BTree:属于多叉树,又名多路平衡查找树。

性质:

  • BTree 的节点存储多个元素( 键值 - 数据 / 子节点 的地址)
  • BTree 节点的键值按 非降序 排列
  • BTree 所有叶子节点都位于同一层(具有相同的深度)

索引 的使用

MySQL 索引 的基本语法

  • 定义 主键约束、外键约束、唯一约束 等约束时 相当于同时在指定列上创建了一个索引

创建表时:

create table table_name([col_name data_type] [unique | fulltext | spatial...],[unique...] [index | key] [index_name] (col_name [length], ...)
);create table user (id INT NOT NULL, name CHAR(30) NOT NULL, unique index uniqueIdx(id)
);

表已存在时:

-- 第一种
alter table table_name add [unique...] [index | key] [index_name] (col_name [length], ...);alter table user add unique index uniqueIdx(id);-- 第二种
create [unique...] index index_name
on table_name (col_name [length], ...);create unique index uniqueIdx on user(id);-- 删除索引drop index index_name on table_name;

怎么判断要不要加索引?

加索引:

  • 数据本身具有某种的性质,如:唯一性、非空性…
  • 频繁进行 分组或排序 的列;如果待排序的列有多个,可以建立 组合索引

不加索引:

  • 经常更新的列
  • 列 的值类型 很少,如 性别
  • where 条件中用不到的列
  • 参与计算的列
  • 数据量小的表

创建了索引,不一定会生效当使用 组合索引 时,如果没有遵循 最左匹配 原则,索引不生效。

例如,创建 id、name、age 组合索引

  • id、(id、name)、(id、name、age)查询,索引生效
  • age、(age、name)查询,索引不生效

判断索引是否生效?

使用 explain 关键字。

  • possible_keys:MySQL 在搜索数据记录时可选用的各个索引
  • key:MySQL 实际选用的索引
explain select * from user where id = 1;

怎么避免索引失效?

  • 使用组合索引时,遵循 最左匹配 原则
  • 不在索引列上进行任何操作,如:计算、函数、类型转换
  • 尽量使用覆盖索引
  • 索引列 尽量不使用 不等于(!= / <>)条件、通配符开头的模糊查询(like %abc)、or 作为连接条件
  • 字符串加单引号(不加可能会发生索引列的隐式转换,导致索引失效)

24.安全管理

管理用户

MySQL用户账号和信息存储在名为mysql的MySQL数据库中。一般不需要直接访问mysql数据库和表(你稍后会明白这一点),但有时需要直接访问。需要直接访问它的时机之一是在需要获得所有用户账号列表时。为此,可使用以下代码

use mysql;
select user from user;

分析

mysql数据库有一个名为user的表,它包含所有用户账号
user表有一个名为user的列,它存储用户登录名

创建用户账号

为了创建一个新用户账号,使用CREATE USER语句

create user  用户名 IDENTIFIED BY '密码';

指定散列口令IDENTIFIED BY指定的口令为纯文本,MySQL将在保存到user表之前对其进行加密。为了作为散列值指定口令,使用IDENTIFIED BY PASSWORD

为重新命名一个用户账号,使用RENAME USER语句

;

删除用户账号

为了删除一个用户账号(以及相关的权限),使用DROP USER语句

drop user 用户名

设置访问权限

在创建用户账号后,必须接着分配访问权限。新创建的用户账号没有访问权限。它们能登录MySQL,但不能看到数据,不能执行任何数据库操作

1.展示用户的权限

show grants for 用户名;

使用grant设置权限,必备:

  1. 要授予的权限;
  2. 被授予访问权限的数据库或表;
  3. 用户名
grant select on crashcourse.* to 用户;

此GRANT允许用户在crashcourse.*(crashcourse数据库的所有表)上使用SELECT
通过只授予SELECT访问权限,用户 对crashcourse数据库中的所有数据具有只读访问权限

每个GRANT添加(或更新)用户的一个权限。MySQL读取所有授权,并根据它们确定权限

GRANT的反操作为REVOKE,用它来撤销特定的权限

revoke select on crashcourse.* from 用户;

这条REVOKE语句取消刚赋予用户 的SELECT访问权限。被撤销的访问权限必须存在,否则会出错

GRANT和REVOKE可在几个层次上控制访问权限

  1. 整个服务器,使用GRANT ALL和REVOKE ALL;
  2. 整个数据库,使用ON database.*;
  3. 特定的表,使用ON database.table;
  4. 特定的列;特定的存储过程
  5. 更多:

未来的授权

使用GRANT和REVOKE时,用户账号必须存在但对所涉及的对象没有这个要求
这允许管理员在创建数据库和表之前设计和实现安全措施
这样做的副作用是,当某个数据库或表被删除时(用DROP语句)
相关的访问权限仍然存在而且,如果将来重新创建该数据库或表,这些权限仍然起作用

简化多次授权

可通过列出各权限并用逗号分隔,将多条

GRANT语句串在一起,如下所示

grant select,insert, on 数据库 to  用户;

更改口令

为了更改用户口令,可使用SET PASSWORD语句

set password for 用户名 = Password('新密码');

SET PASSWORD更新用户口令
新口令必须传递到Password()函 数进行加密

SET PASSWORD还可以用来设置当前的口令

set password = Password('新密码');

在不指定用户名时,SET PASSWORD更新当前登录用户的口令


  1. 0-9\. ↩︎

MYSQL必知必会笔记---【总】相关推荐

  1. MySQL必知必会笔记(一)基础知识和基本操作

    第一章  了解MySQL     数据库       保存有组织的数据的容器.(通常是一个文件或一组文件) 人们经常使用数据库这个术语代替他们使用的软件.这是不正确的,确切的说,数据库软件应称为DBM ...

  2. 读书笔记系列1——MySQL必知必会

    读书笔记系列1--MySQL必知必会 文章目录 读书笔记系列1--MySQL必知必会 MySQL官方文档:https://dev.mysql.com/doc/ 第一章 数据库基础 *2021.11.2 ...

  3. mysql函桌为之一的_MYSQL必知必会读书笔记第十和十一章之使用函数处

    mysql简介 MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理. 拼接字段 存储在数据库表中的 ...

  4. mysql日期维表sql文件_《MySQL必知必会》笔记(SQL练习+建表语句)

    站在巨人的肩上 Standing On Shoulders Of Giants 部分转自:https://www.jianshu.com/p/294502893128 https://blog.csd ...

  5. 【SQL】【读书笔记】《MySQL必知必会》

    本文为<MySQL必知必会>[1]读书笔记,用于总结知识点和框架,仅供参考和交流,如有不妥请联系.由于软件版本更新,书中的一些代码已经不再适用,本文主要从SQL基本语句进行增删减.窗口函数 ...

  6. mysql必知必会的数据_MySQL必知必会--汇 总 数 据

    聚集函数 我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提 供了专门的函数.使用这些函数,MySQL查询可用于检索数据,以便分 析和报表生成.这种类型的检索例子有以下几种. 确定表中行数 ...

  7. 《Mysql必知必会》笔记(一)

    Mysql必知必会 笔记(一) 一.数据库基本概念 数据库 表和模式 列和数据类型 行 主键 外键 SQL 二.Mysql 实用程序 常用命令 三.语句总结 1. 检索数据 注意事项 2. 排序检索数 ...

  8. (自用,无内容,勿点)MySQL必知必会笔记

    MySQL必知必会笔记 基础操作 检索数据 select 排序检索 order by 过滤数据 where 数据过滤 通配符 正则 计算字段 数据处理函数 待续 基础操作 选择数据库:use xxx: ...

  9. 《MySQL必知必会》学习笔记十(增删改语句使用)------掌握部分

    MySQL必知必会知识预览 第一章--了解SQL 第二章--MySQL简介 第三章--使用MySQL 第四章--检索数据 第五章--排序检索数据 第六章--过滤数据 第七章--数据过滤 第八章--用通 ...

  10. 《SQL必知必会(第5版)》挑战题笔记 | 所用DBMS为Mysql,mysql workbench安装

    文章目录 一.安装 step1:mysql安装 step2:mysql workbench安装 二.下载随书资料 三.代码实战练习 2.2 检索单个列 四.MySQL知识点回顾 五.挑战题 2.9挑战 ...

最新文章

  1. Java测试工具使用(1)--Junit
  2. 什么是元宇宙?为何要关注它?
  3. X11: Linux跨网络运行XWindow程序
  4. 直播 | 清华大学郑楚杰:知识增强对话生成中的差异感知知识选择
  5. 分布式数据集训营,从入门到精通,从理论到实践,你不可错过的精品课程!...
  6. CSS选择器与Xpath常用语法及对比
  7. Java提高班(五)深入理解BIO、NIO、AIO
  8. ioctl 详细说明
  9. ASP.NET导入Excel到数据库(SQL)
  10. android(安卓)开源框架——六款【转】
  11. 物理课上该怎样使用计算机,物理课堂教学中怎样使用演示课件.doc
  12. mysql数据库开发环境_MySQL数据库教程-环境与集成开发工具
  13. 8250cdn清零 lh_兄弟 HL-L8250CDN驱动
  14. centos是什么操作系统
  15. 删除脚注或尾注的横线
  16. 需求分析(团队作业3)
  17. 针对商品标题冗长问题,阿里工程师怎么解决?
  18. 熊猫烧香版《菊花台》pk《菊花台》
  19. 2006年最热门的职业
  20. 抖音视频链接数据分析

热门文章

  1. Fast Convergence of DETR with Spatially Modulated Co-Attention
  2. 只要几步,微信小程序就能转为APP
  3. 方盒与三角网格碰撞检测
  4. 实在智能发布会带你见证什么是真正属于你的神机百炼?
  5. 使用 axios 拦截器解决「 前端并发冲突 」 问题
  6. 大数据Flink电商数仓实战项目流程全解(一)
  7. Java Spring框架入门详解教程【多测师_何sir】
  8. 关于家用电器的英语单词
  9. 还不懂目标检测嘛?一起来看看Faster R-CNN源码解读
  10. java实现EPA碰撞_使用聚合EPA的派生事件属性中的FIWARE CEP(质子)错误