MySQL学习笔记-基础篇1

MySQL 学习笔记–基础篇1

目录

  • MySQL 学习笔记--基础篇1
  • 1. 数据库概述与MySQL安装
    • 1.1 数据库概述
      • 1.1.1 为什么要使用数据库
    • 1.2 数据库与数据库管理系统
      • 1.2.1 数据库的相关
      • 1.2.2 数据库与数据库管理系统的关系
      • 1.2.3 常见的数据库管理系统排名(DBMS)
    • 1.3 MySQL简介
      • 1.3.1 概述
      • 1.3.2 MySQL发展史重大事件
      • 1.3.3关于MySQL8.0
      • 1.3.4 为什么选择MySQL
      • 1.3.5 Oracle VS MySQL
    • 1.4 RDBMS 与 非RDBMS
      • 1.4.1 关系型数据库(RDBMS)
      • 1.4.2 非关系型数据库(非RDBMS)
    • 1.5 关系型数据库设计规则
      • 1.5.1 表、记录、字段
      • 1.5.2 表的关联关系
    • 1.2 MySQL环境搭建
      • 1.2.1 MySQL 的卸载
      • 1.2.2 MySQL的下载、安装、配置
    • 1.3 MySQL登录
      • 1.3.1 服务的启动与停止
      • 1.2.4MySQL演示使用
      • 1.2.5 MySQL图形化管理工具
      • 1.2.6 MySQL目录结构与源码
  • 2.基本的select语句
    • 2.1 SQL 概述
      • 2.1.1 SQL背景知识
      • 2.1.2 SQL 分类
    • 2.2 SQL语言的规则与规范
      • 2.2.1
      • 2.2.2SQL大小写规范(建议遵守)
      • 2.2.3 注释
      • 2.2.4命名规则(暂时了解)
      • 2.2.5 数据导入指令
    • 2.3基本select 语句
      • 2.3.1SELECT…FROM
      • 2.3.2列的别名
      • 2.3.3去除重复行
      • 2.3.4空值参与运算
      • 2.3.5 着重号
    • 2.4 显示表结构
    • 2.5过滤数据
  • 3.运算符
    • 3.1 算术运算符
    • 3.2 比较运算符
    • 3.3逻辑运算符
    • 3.4 位运算符
    • 3.5 运算符的优先级
    • 3.6 拓展:使用正则表达式查询
  • 4.排序与分页
    • 4.1 排序数据
    • 4.2 分页
  • 5 .多表查询
    • 5.1 一个案例引发的多表连接
      • 5.1.1 案例说明
      • 5.1.2 笛卡尔积(或交叉连接)的理解
      • 5.1.3案例分析与问题解决
    • 5.2 多表查询分类讲解
    • 5.3 SQL99 语法实现多表查询
      • 5.3.1 基本语法
      • 5.3.2 内连接(INNER JOIN)的实现
      • 5.3.3 外连接(OUTER JOIN) 的实现
    • 5.4 UNION 的使用
    • 5.5 7中SQL JOINS的实现
      • 5.5.1代码实现
      • 5.5.2 语法格式小结
    • 5.6 SQL99语法新特性
      • 5.6.1 自然连接
      • 5.6.2USING连接
    • 5.7 小结
  • 6.单行函数
    • 6.1函数的理解
      • 6.1.1 什么是函数
      • 6.1.2 不同DBMS函数的差异
      • 6.1.3 MySQL 的内置函数及分类
    • 6.2 数值函数
      • 6.2.1 基本函数
      • 6.2.2 角度与弧度互换函数
      • 6.2.3 三角函数
      • 6.2.4 指数与对数
      • 6.2.5进制间的转换
    • 6.3字符串函数
    • 6.4日期和时间函数
      • 6.4.1获取日期、时间
      • 6.4.2日期与时间戳的转换
      • 6.4.3获取月份、星期、星期数、天数等函数
      • 6.4.4 日期的操作函数
      • 6.4.5 时间和秒钟转换函数
      • 6.4.6 计算日期和时间的函数
      • 6.4.7 日期的格式化与解析
    • 6.5 流程控制
    • 6.6 加密解密函数
    • 6.7 MySQL 信息函数
    • 6.8 其他函数
  • 7. 聚合函数
    • 7.1 集合函数介绍
      • 7.1.1AVG和SUM函数
      • 7.1.2 MIN 和MAX函数
      • 7.1.3 COUNT 函数
    • 7.2 GROUP BY
      • 7.2.1基本使用
      • 7.2.2 使用多个列分组
      • 7.2.3 GROUP BY 中使用WITH ROLLUP
    • 7.3 HAVING
      • 7.3.1 基本使用
      • 7.3.2 WHERE 和HAVING对比
    • 7.4 SELECT的执行过程。
      • 7.4.1查询的结构
      • 7.4.2 SELECT 执行顺序
      • 7.4.3SQL的执行原理

1. 数据库概述与MySQL安装

1.1 数据库概述

1.1.1 为什么要使用数据库

  • 持久化(persistence):把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,持久化意味着将内存中的数据保存到硬盘上加以“固化”,而持久化的实现过程大多通过各种关系数据库来完成。
  • 持久化的主要作用是将内存中的数据存储到关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。
    MySQL学习笔记-基础篇1_第1张图片

1.2 数据库与数据库管理系统

1.2.1 数据库的相关

  • DB: 数据库(Database)
  • 即存储数据的“仓库”,其本质是一个文件系统。它保存了一系列有组织的数据
  • DBMS:数据库管理系统(Database Management System)
  • 是一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一的管理和控制。用户通过数据库管理系统访问数控中表内的数据。
  • SQL:结构化查询语言(Structured Query Language)
  • 专门用来与数据库通信的语言。

1.2.2 数据库与数据库管理系统的关系

  • 数控管理系统(DBMS)可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库创建多个表,以保存程序中实体用户数据。
  • 数据库管理系统、数据库和表的关系如图所示:
    MySQL学习笔记-基础篇1_第2张图片MySQL学习笔记-基础篇1_第3张图片

1.2.3 常见的数据库管理系统排名(DBMS)

  • 目前互联网上常见的数据库管理软件有Oracle、MySQL、MS SQL Server、DB2、PostgreSQL、Access、Sybase、Informix这几种。以下是2021年DB-Engines Ranking 对各数据库受欢迎程度进行调查后的统计结果:查看数据库最新排名 对应的走势图
  • 最新排名
    MySQL学习笔记-基础篇1_第4张图片
  • 走势图
    MySQL学习笔记-基础篇1_第5张图片### 1.2.4 常见数据介绍
  • Oracle
  • 1979 年,Oracle 2 诞生,它是第一个商用的 RDBMS(关系型数据库管理系统)。随着 Oracle 软件的名气越来越大,公司也改名叫 Oracle 公司。
  • 2007年,总计85亿美金收购BEA Systems。 2009年,总计74亿美金收购SUN。此前的2008年,SUN以10亿美金收购MySQL。意味着Oracle 同时拥有了MySQL 的管理权,至此 Oracle 在数据库领域中成为绝对的领导者。
  • 2013年,甲骨文超越IBM,成为继Microsoft后全球第二大软件公司。
  • 如今 Oracle 的年收入达到了 400 亿美金,足以证明商用(收费)数据库软件的价值。
  • SQL Server
  • SQL Server 是微软开发的大型商业数据库,诞生于 1989 年。C#、.net等语言常使用,与WinNT完全集成,也可以很好地与Microsoft BackOffice产品集成。
  • DB2
  • IBM公司的数据库产品,收费的。常应用在银行系统中。
  • PostgreSQL
  • PostgreSQL 的稳定性极强,最符合SQL标准,开放源码,具备商业级DBMS质量。PG对数据量大的文本以及SQL处理较快。
  • SQLite
  • 嵌入式的小型数据库,应用在手机端。 零配置,SQlite3不用安装,不用配置,不用启动,关闭或者配置数据库实例。当系统崩溃后不用做任何恢复操作,再下次使用数据库的时候自动恢复。
  • informix
  • IBM公司出品,取自Information 和Unix的结合,它是第一个被移植到Linux上的商业数据库产品。仅运行于unix/linux平台,命令行操作。 性能较高,支持集群,适应于安全性要求极高的系统,尤其是银行,证券系统的应用。

1.3 MySQL简介

MySQL学习笔记-基础篇1_第6张图片

1.3.1 概述

  • MySQL是一个 开放源代码的关系型数据库管理系统 ,由瑞典MySQL AB(创始人Michael Widenius)公 司1995年开发,迅速成为开源数据库的 No.1。
  • 2008被 Sun 收购(10亿美金),2009年Sun被 Oracle 收购。 MariaDB 应运而生。(MySQL 的创造者担心 MySQL 有闭源的风险,因此创建了 MySQL 的分支项目 MariaDB)
  • MySQL6.x 版本之后分为 社区版商业版
  • MySQL是一种关联数据库管理系统,将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
  • MySQL是开源的,所以你不需要支付额外的费用。
  • MySQL是可以定制的,采用了 GPL(GNU General Public License) 协议,你可以修改源码来开发自己的MySQL系统。
  • MySQL支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
  • MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持 4GB ,64位系统支持最大的表文件为 8TB
  • MySQL使用 标准的SQL数据语言 形式。
  • MySQL可以允许运行于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、 Java、Perl、PHP和Ruby等。

1.3.2 MySQL发展史重大事件

MySQL的历史就是整个互联网的发展史。互联网业务从社交领域、电商领域到金融领域的发展,推动着应用对数据库的需求提升,对传统的数据库服务能力提出了挑战。高并发、高性能、高可用、轻资源、易维护、易扩展的需求,促进了MySQL的长足发展。

MySQL学习笔记-基础篇1_第7张图片

1.3.3关于MySQL8.0

MySQL从5.7版本直接跳跃发布了8.0版本 ,可见这是一个令人兴奋的里程碑版本。MySQL 8版本在功能上做了显著的改进与增强,开发者对MySQL的源代码进行了重构,最突出的一点是多MySQL Optimizer优化器进行了改进。不仅在速度上得到了改善,还为用户带来了更好的性能和更棒的体验。

1.3.4 为什么选择MySQL

MySQL学习笔记-基础篇1_第8张图片为什么如此多的厂商要选用MySQL?大概总结的原因主要有以下几点:

  • 开放源代码,使用成本低。
  • 性能卓越,服务稳定。
  • 软件体积小,使用简单,并且易于维护。
  • 历史悠久,社区用户非常活跃,遇到问题可以寻求帮助。
  • 许多互联网公司在用,经过了时间的验证。

1.3.5 Oracle VS MySQL

  • Oracle 更适合大型跨国企业的使用,因为他们对费用不敏感,但是对性能要求以及安全性有更高的要求。
  • MySQL 由于其体积小、速度快、总体拥有成本低,可处理上千万条记录的大型数据库,尤其是开放源码这一特点,使得很多互联网公司、中小型网站选择了MySQL作为网站数据库(Facebook,Twitter, YouTube,阿里巴巴/蚂蚁金服,去哪儿,美团外卖,腾讯)。

1.4 RDBMS 与 非RDBMS

  • 从排名中我们能看出来,关系型数据库绝对是 DBMS 的主流,其中使用最多的 DBMS 分别是 Oracle、 MySQL 和 SQL Server。这些都是关系型数据库(RDBMS)。

1.4.1 关系型数据库(RDBMS)

  • 实质
  • 这种类型的数据库是 最古老 的数据库类型,关系型数据库模型是把复杂的数据结构归结为简单的二元关系 (即二维表格形式)。
    MySQL学习笔记-基础篇1_第9张图片- 关系型数据库以 行(row)列(column) 的形式存储数据,以便于用户理解。这一系列的行和列被
  • 优势
  • 复杂查询 可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
  • 事务支持 使得对于安全性能很高的数据访问要求得以实现。

1.4.2 非关系型数据库(非RDBMS)

  • 介绍
  • 非关系型数据库,可看成传统关系型数据库的功能 阉割版本,基于键值对存储数据,不需要经过SQL层的解析, 性能非常高 。同时,通过减少不常用的功能,进一步提高性能。
  • 目前基本上大部分主流的非关系型数据库都是免费的。
  • 有哪些非关系型数据库
  • 相比于 SQL,NoSQL 泛指非关系型数据库,包括了榜单上的键值型数据库、文档型数据库、搜索引擎和列存储等,除此以外还包括图形数据库。也只有用 NoSQL 一词才能将这些技术囊括进来。
  • 键值型数据库
  • 键值型数据库通过 Key-Value 键值的方式来存储数据,其中 Key 和 Value 可以是简单的对象,也可以是复杂的对象。Key 作为唯一的标识符,优点是查找速度快,在这方面明显优于关系型数据库,缺点是无法像关系型数据库一样使用条件过滤(比如 WHERE),如果你不知道去哪里找数据,就要遍历所有的键,这就会消耗大量的计算。
  • 键值型数据库典型的使用场景是作为 内存缓存Redis 是最流行的键值型数据库
    MySQL学习笔记-基础篇1_第10张图片- 文档型数据库
  • 此类数据库可存放并获取文档,可以是XML、JSON等格式。在数据库中文档作为处理信息的基本单位,一个文档就相当于一条记录。文档数据库所存放的文档,就相当于键值数据库所存放的“值”
  • MongoDB是最流行的文档型数据库。此外,还有CouchDB等。
  • 搜索引擎数据库
  • 虽然关系型数据库采用了索引提升检索效率,但是针对全文索引效率却较低。搜索引擎数据库是应用在搜索引擎领域的数据存储形式,由于搜索引擎会爬取大量的数据,并以特定的格式进行存储,这样在检索的时候才能保证性能最优。核心原理是“倒排索引”。
  • 典型产品:Solr、Elasticsearch、Splunk 等。
    列式数据库
  • 列式数据库是相对于行式存储的数据库,Oracle、MySQL、SQL Server 等数据库都是采用的行式存储(Row-based),而列式数据库是将数据按照列存储到数据库中,这样做的好处是可以大量降低系统的I/O,适合于分布式文件系统,不足在于功能相对有限。典型产品:HBase等。
    MySQL学习笔记-基础篇1_第11张图片
  • 图形数据库
  • 图形数据库,利用了图这种数据存储结构存储了实体(对象)之间的关系。图形数据库最典型的例子就是社交网络中人与人的关系,数据模型主要是以节点和边(关系)来实现,特点在于能高效地解决复杂的关系问题。
  • 图形数据库顾名思义,就是一种存储图形关系的数据库。它利用了图这种数据结构存储了实体(对象)之间的关系。关系型数据用于存储明确关系的数据,但对于复杂关系的数据存储却有些力不从心。如社交网络中人物之间的关系,如果用关系型数据库则非常复杂,用图形数据库将非常简单。典型产品:Neo4J、InfoGrid等。
    MySQL学习笔记-基础篇1_第12张图片
  • NoSQL的演变
    由于 SQL 一直称霸 DBMS,因此许多人在思考是否有一种数据库技术能远离 SQL,于是 NoSQL 诞生了,但是随着发展却发现越来越离不开 SQL。到目前为止 NoSQL 阵营中的 DBMS 都会有实现类似 SQL 的功能。下面是“NoSQL”这个名词在不同时期的诠释,从这些释义的变化中可以看出 NoSQL 功能的演变 :
    1970:NoSQL = We have no SQL
    1980:NoSQL = Know SQL
    2000:NoSQL = No SQL!
    2005:NoSQL = Not only SQL
    2013:NoSQL = No, SQL!
    NoSQL 对 SQL 做出了很好的补充,比如实际开发中,有很多业务需求,其实并不需要完整的关系型数据库功能,非关系型数据库的功能就足够使用了。这种情况下,使用 性能更高 、 成本更低 的非关系型数据库当然是更明智的选择。比如:日志收集、排行榜、定时器等。

1.5 关系型数据库设计规则

  • 关系型数据的典型数据结构是 数据表, 这些数据表的组成都是结构化的(Structured)。
  • 将数据放到表中,表再放到库中。
  • 一个数据库中可以放多个表,每个表都有一个名字,用来标识自己。表名具有唯一性。
  • 表具有一些特性,这些特性定义了数据在表中如何存储,类似java和python中“类”的设计。

1.5.1 表、记录、字段

  • E-R(entity-relationship,实体-联系)模型中有三个主要概念是: 实体集属性联系集
  • 一个实体集(class)对应于数据库中的一个表(table),一个实体(instance)则对应于数据库表中的一行(row),也称为一条记录(record)。一个属性(attribute)对应于数据库表中的一列(column),也称为一个字段(field)。

MySQL学习笔记-基础篇1_第13张图片

1.5.2 表的关联关系

  • 表与表之间的数据记录有关系(relationship)。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。
  • 四种:一对一关联、一对多关联、多对多关联、自我引用
  • 一对一关联(one-to-one)
  • 在实际的开发中应用不多,因为一对一可以创建成一张表。
  • 举例:设计 学生表 :学号、姓名、手机号码、班级、系别、身份证号码、家庭住址、籍贯、紧急联系人、…
  • 拆为两个表:两个表的记录是一一对应关系。
  • 基础信息表 (常用信息):学号、姓名、手机号码、班级、系别
  • 档案信息表 (不常用信息):学号、身份证号码、家庭住址、籍贯、紧急联系人、…
  • 两种建表原则:
  • 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一。
  • 外键是主键:主表的主键和从表的主键,形成主外键关系。
    MySQL学习笔记-基础篇1_第14张图片
  • 一对多关系(one-to-many)
  • 常见实例场景: 客户表和订单表 , 分类表和商品表 , 部门表和员工表 。
  • 举例:
  • 员工表:编号、姓名、…、所属部门
  • 部门表:编号、名称、简介
  • 一对多建表原则:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
    MySQL学习笔记-基础篇1_第15张图片MySQL学习笔记-基础篇1_第16张图片- 多对多关系(many-to-many)
  • 要表示多对多关系,必须创建第三个表,该表通常称为 联接表 ,它将多对多关系划分为两个一对多关系。将这两个表的主键都插入到第三个表中。
    MySQL学习笔记-基础篇1_第17张图片
  • 举例1:学生-课表
  • 学生信息表:一行代表一个学生的信息(学号、姓名、手机号、班级、系别……)
  • 课程信息表:一行代表一个课程(课程编号,授课老师,简介……)
  • 选课信息表:一个学生可以选多门课,一门课也可以被多个学生选
    MySQL学习笔记-基础篇1_第18张图片- 举例2:产品-订单

“订单”表和“产品”表有一种多对多的关系,这种关系是通过与“订单明细”表建立两个一对多关系来
定义的。一个订单可以有多个产品,每个产品可以出现在多个订单中。

  • 产品表:“产品”表中的每条记录表示一个产品
  • 订单表:“订单”表中的每条记录表示一个订单
  • 订单明细表:每个产品可以与“订单”表中的多条记录对应,即出现多个订单。一个订单可以与多个“产品”表中的多条记录对应,即包含多个产品。
    MySQL学习笔记-基础篇1_第19张图片- 举例3:用户-角色
    多堆垛关系建表原则:需要创建第三张表,中间表至少包含俩个字段,这俩个字段分别作为外键指向各自一方的主键。
    MySQL学习笔记-基础篇1_第20张图片- 自我引用(Self reference)

MySQL学习笔记-基础篇1_第21张图片

1.2 MySQL环境搭建

1.2.1 MySQL 的卸载

  • 停止MySQL服务

在卸载之前,先停止MySQL8.0的服务。按键盘上的“Ctrl + Alt + Delete”组合键,打开“任务管理器”对话框,可以在“服务”列表找到“MySQL8.0”的服务,如果现在“正在运行”状态,可以右键单击服务,选择“停 止”选项停止MySQL8.0的服务,如图所示。
MySQL学习笔记-基础篇1_第22张图片

  • 软件卸载

卸载MySQL8.0的程序可以和其他桌面应用程序一样直接在“控制面板”选择“卸载程序”,并在程序列表中找到MySQL8.0服务器程序,直接双击卸载即可,如图所示。这种方式删除,数据目录下的数据不会跟着删除。

  • 删除残余文件的清理

  • 如果再次安装不成功,可以卸载后对残余文件进行清理后再安装。

  • 服务目录:mysql服务的安装目录

  • 数据目录:默认在C:\ProgramData\MySQL(如果自己单独指定了数据目录,找到指定的位置进行删除)

  • 清理注册表(选)

  • 如果前面几步做了,再次安装还是失败,可以清理注册表

  • 打开方式:在系统的搜索框中输入regedit
    MySQL学习笔记-基础篇1_第23张图片注册表中的ControlSet001,ControlSet002,不一定是001和002,可能是ControlSet005、006之类

  • 删除环境变量配置

  • 找到python环境变量,将其中关于mysql的环境变量删除,切记不要全部删除

1.2.2 MySQL的下载、安装、配置

  • MySQL Community Server 社区版本,开源免费,自由下载,但不提供官方技术支持,适用于
    大多数普通用户。
  • MySQL Enterprise Edition 企业版本,需付费,不能在线下载,可以试用30天。提供了更多的
    功能和更完备的技术支持,更适合于对数据库的功能和可靠性要求较高的企业客户。
  • MySQL Cluster 集群版,开源免费。用于架设集群服务器,可将几个MySQL Server封装成一个
    Server。需要在社区版或企业版的基础上使用。
  • MySQL Cluster CGE 高级集群版,需付费。

官方还提供了 MySQL Workbench (GUITOOL)一款专为MySQL设计的 图形界面管理工具 。 MySQLWorkbench又分为两个版本,分别是 社区版 (MySQL Workbench OSS)、 商用版 (MySQL WorkbenchSE)。

  • 软件下载
  • 下载地址官网
  • Windows下的MySQL8.0安装有两种安装程序
  • mysql-installer-web-community-8.0.26.0.msi 下载程序大小:2.4M;安装时需要联网安
    装组件。
  • mysql-installer-community-8.0.26.0.msi 下载程序大小:450.7M;安装时离线安装即
    可。推荐
  • 如果安装MySQL5.7版本的话,选择 Archives ,接着选择MySQL5.7的相应版本即可。这里下载最近期的MySQL5.7.34版本。
  • MySQL8.0版本安装
  • MySQL下载完成后,找到下载文件,双击进行安装,具体操作步骤如下。
  • 步骤1:双击下载的mysql-installer-community-8.0.26.0.msi文件,打开安装向导。
  • 步骤2:打开“Choosing a Setup Type”(选择安装类型)窗口,在其中列出了5种安装类型,分别是Developer Default(默认安装类型)、Server only(仅作为服务器)、Client only(仅作为客户端)、Full(完全安装)、Custom(自定义安装)。这里选择“Custom(自定义安装)”类型按钮,单击“Next(下一步)”按钮。

MySQL学习笔记-基础篇1_第24张图片

  • 步骤3:打开“Select Products” (选择产品)窗口,可以定制需要安装的产品清单。例如,选择“MySQL Server 8.0.26-X64”后,单击“→”添加按钮,即可选择安装MySQL服务器,如图所示。采用通用的方法,可以添加其他你需要安装的产品。
    MySQL学习笔记-基础篇1_第25张图片此时如果直接“Next”(下一步),则产品的安装路径是默认的。如果想要自定义安装目录,则可以选中对应的产品,然后在下面会出现“Advanced Options”(高级选项)的超链接。
    MySQL学习笔记-基础篇1_第26张图片ProgramData目录(这是一个隐藏目录)。如果自定义安装目录,请避免“中文”目录。另外,建议服务目录和数据目录分开存放。
    MySQL学习笔记-基础篇1_第27张图片- 步骤4:在上一步选择好要安装的产品之后,单击“Next”(下一步)进入确认窗口,如图所示。单击
    “Execute”(执行)按钮开始安装
    MySQL学习笔记-基础篇1_第28张图片- 步骤5:安装完成后在“Status”(状态)列表下将显示“Complete”(安装完成),如图所示。
    MySQL学习笔记-基础篇1_第29张图片
  • 配置MySQL8.0

MySQL安装之后,需要对服务器进行配置。具体的配置步骤如下。

  • 步骤1:在上一个小节的最后一步,单击“Next”(下一步)按钮,就可以进入产品配置窗口。
    MySQL学习笔记-基础篇1_第30张图片MySQL学习笔记-基础篇1_第31张图片其中,“Config Type”选项用于设置服务器的类型。单击该选项右侧的下三角按钮,即可查看3个选项,如图所示。

MySQL学习笔记-基础篇1_第32张图片

  • Server Machine(服务器) :该选项代表服务器,MySQL服务器可以同其他服务器应用程序一起运行,例如Web服务器等。MySQL服务器配置成适当比例的系统资源。

  • Dedicated Machine(专用服务器) :该选项代表只运行MySQL服务的服务器。MySQL服务器配置成使用所有可用系统资源。

  • 步骤3:单击“Next”(下一步)按钮,打开设置授权方式窗口。其中,上面的选项是MySQL8.0提供的新的授权方式,采用SHA256基础的密码加密方法;下面的选项是传统授权方法(保留5.x版本兼容性)。

  • MySQL学习笔记-基础篇1_第33张图片- 步骤4:单击“Next”(下一步)按钮,打开设置服务器root超级管理员的密码窗口,如图所示,需要输入两次同样的登录密码。也可以通过“Add User”添加其他用户,添加其他用户时,需要指定用户名、允许该用户名在哪台/哪些主机上登录,还可以指定用户角色等。此处暂不添加用户,用户管理在MySQL高级特性篇中讲解。
    MySQL学习笔记-基础篇1_第34张图片

  • 步骤5:单击“Next”(下一步)按钮,打开设置服务器名称窗口,如图所示。该服务名会出现在Windows服务列表中,也可以在命令行窗口中使用该服务名进行启动和停止服务。本书将服务名设置为“MySQL80”。如果希望开机自启动服务,也可以勾选“Start the MySQL Server at System Startup”选项(推荐)。

  • 下面是选择以什么方式运行服务?可以选择“Standard System Account”(标准系统用户)或者“Custom User” (自定义用户)中的一个。这里推荐前者。

  • MySQL学习笔记-基础篇1_第35张图片MySQL学习笔记-基础篇1_第36张图片

  • 步骤7:完成配置,如图所示。单击“Finish”(完成)按钮,即可完成服务器的配置。

  • 步骤8:如果还有其他产品需要配置,可以选择其他产品,然后继续配置。如果没有,直接选择“Next”(下一步),直接完成整个安装和配置过程。

  • 步骤9:结束安装和配置。

如果不配置MySQL环境变量,就不能在命令行直接输入MySQL登录命令。下面说如何配置MySQL的环境变量:

  • 步骤1:在桌面上右击【此电脑】图标,在弹出的快捷菜单中选择【属性】菜单命令。
  • 步骤2:打开【系统】窗口,单击【高级系统设置】链接。
  • 步骤3:打开【系统属性】对话框,选择【高级】选项卡,然后单击【环境变量】按钮。
  • 步骤4:打开【环境变量】对话框,在系统变量列表中选择path变量。
  • 步骤5:单击【编辑】按钮,在【编辑环境变量】对话框中,将MySQL应用程序的bin目录(C:\Program Files\MySQL\MySQL Server 8.0\bin)添加到变量值中,用分号将其与其他路径分隔开。
  • 步骤6:添加完成之后,单击【确定】按钮,这样就完成了配置path变量的操作,然后就可以直接输入MySQL命令来登录数据库了。

1.3 MySQL登录

1.3.1 服务的启动与停止

  • MySQL安装完毕后,需要启动服务器进程,不然客户端无法连接数据库
  • 在前面的配置过程中,已经将MySQL安装为Windows服务,并且勾选当Windows启动、停止,MySQL也自动启动、停止。
  • 使用图形界面工具
  • 步骤1:打开windows服务
  • 方式1:计算机(点击鼠标右键)→ 管理(点击)→ 服务和应用程序(点击)→ 服务(点
    击)
  • 方式2:控制面板(点击)→ 系统和安全(点击)→ 管理工具(点击)→ 服务(点击)
  • 方式3:任务栏(点击鼠标右键)→ 启动任务管理器(点击)→ 服务(点击)
  • 方式4:单击【开始】菜单,在搜索框中输入“services.msc”,按Enter键确认
  • 步骤2:找到MySQL80(点击鼠标右键)→ 启动或停止(点击)
    MySQL学习笔记-基础篇1_第37张图片
# 启动 MySQL 服务命令: 
net start MySQL服务名 
# 停止 MySQL 服务命令: 
net stop MySQL服务名

说明:

  1. start和stop后面的服务名应与之前配置时指定的服务名一致。
  2. 如果当你输入命令后,提示“拒绝服务”,请以 系统管理员身份 打开命令提示符界面重新尝试。
  • 自带客户端的登录与退出
  • 当MySQL服务启动完成后,便可以通过客户端来登录MySQL数据库。注意:确认服务是开启的。
  • 登录方式1:MySQL自带客户端

开始菜单 → 所有程序 → MySQL → MySQL 8.0 Command Line Client
MySQL学习笔记-基础篇1_第38张图片仅限root用户

  • 格式
mysql -h 主机名 -P 端口号 -u 用户名 -p密码
  • 举例:
mysql -h localhost -P 3306 -u root -proot # 这里设置的root密码是root
  • 注意点
    1.-p与密码之间不能有空格,其它参数名与参数值之间可以有空格也可以没有空格
    2.密码建议在下一行输入,保证安全
mysql -h localhost -P 3306 -u root -p
Enter password:****

3.客户和服务器在同一台机器上,所以输入localhost 或者IP地址127.0.0.1。同时因为是连接本机:-h
localhost 可以省略,如果端口没有修改:-P3306也可以省略。

  • 登录后退出
  • exit或quit

1.2.4MySQL演示使用

  • 查看所有数据库
show database;
  • “information_schema”是 MySQL 系统自带的数据库,主要保存 MySQL 数据库服务器的系统信息,比如数据库的名称、数据表的名称、字段名称、存取权限、数据文件 所在的文件夹和系统使用的文件夹,等等

  • “performance_schema”是 MySQL 系统自带的数据库,可以用来监控 MySQL 的各类性能指标。

  • “sys”数据库是 MySQL 系统自带的数据库,主要作用是以一种更容易被理解的方式展示 MySQL 数据库服务器的各类性能指标,帮助系统管理员和开发人员监控 MySQL 的技术性能。

  • “mysql”数据库保存了 MySQL 数据库服务器运行时需要的系统信息,比如数据文件夹、当前使用的字符集、约束检查信息,等等

  • 创建自己数据库

create database 数据库名;
# 创建的数据库名不能已经存在
  • 使用自己的数据库
use 数据库名;
  • 说明:如果没有使用use语句,后面针对数据库的操作也没有加“数据名”的限定,会报ERROR1046(3D000): No database selected”(没有选择数据库)

  • 使用完use语句之后,如果接下来的SQL都是针对一个数据库操作的,那就不用重复use了,如果要针对另一个数据库操作,那么要重新use。

  • 查看某个库的所有表格

show tables from 数据库名;
  • 创建新表格
create table 表名称(
	字段名 数据类型,
	字段名 数据类型
)

说明:如果是最后一个字段,后面就不用加逗号,因为逗号的作用是分割每个字段

  • 示例:创建学生表
create table student (
	id int,
	name varchar(20)  # 说明字最长不超过20个字符
)
  • 查看一个表的数据
select * from 数据库表名称;
# 查看学生表的数据
select * from student;
  • 添加一条记录
insert into 表名称 values(值列表);

# 添加记录进student
inster into student values(1,'张三');
  • 符号需要英文符号,中文的会报错

  • 查看表的创建信息

show create table 表名称;

# 查看student表的详细创建信息
show create table student;
#MySQL5.7
Table: student 
Create Table: CREATE TABLE `student` (
	 `id` int(11) DEFAULT NULL, 
	 `name` varchar(20) DEFAULT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1 
 1 row in set (0.00 sec)

在MySQL5.7中默认字符集是“latin1”不支持中文可以修改mv.ini文件,MySQL8.0默认是utf-8

  • 查看数据库的创建信息
show create database 数据库名;
  • 删除表格
drop table 表名称;
  • 删除数据库
drop database 数据库名;

1.2.5 MySQL图形化管理工具

  • MySQL图形化管理工具极大地方便了数据库的操作与管理,常用的图形化管理工具有:MySQL Workbench、phpMyAdmin、Navicat Preminum、MySQLDumper、SQLyog、dbeaver、MySQL ODBC Connector。
  • 推荐使用Navicat,SQLyog

1.2.6 MySQL目录结构与源码

  • 主要目录结构:
  • bin目录:所有MySQL的可执行文件,如:mysql.exe
  • MySQLInstanceConfig.exe:数据库的配置向导,安装时出现的内容
  • data目录:系统数据库所在的目录
  • my.ini文件:MySQL的主要配置文件
  • c:\ProgramData\MySQL\MySQL Server8.9\data:用户创建的数据库所在的目录。

2.基本的select语句

2.1 SQL 概述

2.1.1 SQL背景知识

  • 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖。在这几十年里,无数的技术、产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰。但在这片浩荡的波动里,有一门技术从未消失,甚至“老当益壮”,那就是 SQL。
  • 45 年前,也就是 1974 年,IBM 研究员发布了一篇揭开数据库技术的论文《SEQUEL:一门结构化的英语查询语言》,直到今天这门结构化的查询语言并没有太大的变化,相比于其他语言, SQL 的半衰期可以说是非常长 了。
  • 不论是前端工程师,还是后端算法工程师,都一定会和数据打交道,都需要了解如何又快又准确地提取自己想要的数据。更别提数据分析师了,他们的工作就是和数据打交道,整理不同的报告,以便指导业务决策。
  • SQL(Structured Query Language,结构化查询语言)是使用关系模型的数据库应用语言, 与数据直 接打交道 ,由 IBM 上世纪70年代开发出来。后由美国国家标准局(ANSI)开始着手制定SQL标准,先后有 SQL-86 , SQL-89 , SQL-92 , SQL-99 等标准。
  • SQL 有两个重要的标准,分别是 SQL92 和 SQL99,它们分别代表了 92 年和 99 年颁布的 SQL 标准,我们今天使用的 SQL 语言依然遵循这些标准。
  • 不同的数据库生产厂商都支持SQL语句,但都有特有内容。
    MySQL学习笔记-基础篇1_第39张图片- 自从 SQL 加入了 TIOBE 编程语言排行榜,就一直保持在 Top 10。

2.1.2 SQL 分类

  • SQL语言在功能上主要分为3大类
  • DDL (Data Definition Languages、数据定义语言),这些语句定义了不同的数据库、表、视图、索引等数据库对象,还可以用来创建、删除、修改数据库和数据表的结构。主要的语句关键字包括 CREATE 、 DROP 、 ALTER 等。
  • DML (Data Manipulation Language、数据操作语言),用于添加、删除、更新和查询数据库记录,并检查数据完整性。主要的语句关键字包括 INSERT 、 DELETE 、 UPDATE 、 SELECT 等。SELECT是SQL语言的基础,最为重要。
  • DCL (Data Control Language、数据控制语言) ,用于定义数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 GRANT 、 REVOKE 、 COMMIT 、 ROLLBACK 、 SAVEPOINT 等

-因为查询语句使用的非常频繁,所有很多人把查询语句单拎出来一类:DQL(数据查询语句),还有单独将COMMIT,ROLLBACK取出来称为TCL(Transaction Control Language,事务控制语言)。

2.2 SQL语言的规则与规范

2.2.1

  • SQL可以写在一行或者多行,为了提高可读性,各子句分行写,必要时使用缩进
  • 每条命令以;或\g或\G结束
  • 关键字不能被缩写也不能分行
  • 关于标点符号
    • 必须保证所有的()、单引号、双引号都是成对结束的
    • 必须使用英文状态下的半角输入方式
    • 字符串型和日期类型的数据可以使用单引号(‘’)表示
    • 列的别名,尽量使用双引号(“”) ,而且不建议省略

2.2.2SQL大小写规范(建议遵守)

  • MySQL在Windows环境下时大小写不敏感的。
  • MySQL在Linux环境下时大小写敏感的
    • 数据库名、表名、表的别名、变量名是严格区分大小写的
    • 关键字、函数名、列名(或字段名)、列的别名(字段的别名)是忽略大小写的
  • 推荐采用统一的书写规范
    • 数据库名 、表名、表别名、字段名、字段别名等都是小写
    • SQL关键字、函数名、绑定变量等都是大写

2.2.3 注释

  • 可以使用如下格式的注释结构
单行注释 :# 注释文字(MySQL特有的方式)
单行注释:-- 注释文字(-- 后面必须包含一个空格)
多行注释:/* 注释文字 */

2.2.4命名规则(暂时了解)

  • 数据库、表名不得超过30个字符,变量名限制为29个

  • 必须只能包含 A–Z, a–z, 0–9, _共63个字符

  • 数据库名、表名、字段名等对象名中间不要包含空格

  • 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名

  • 必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使用`(着重号)引起来

  • 保持字段名和类型的一致性,在命名字段并为其指定数据类型的时候一定要保证一致性。假如数据类型在一个表里是整数,那在另一个表里可就别变成字符型了

  • 举例

# 以下俩句是一样的,不区分大小写
show database;
show DATABASE;

# 创建表格
# create table student info(……);# 表名错误,因为表名有空格
create table student_info(……)

# 其中order 使用	``飘号,因为order和系统关键字或系统函数名等定义标识符重名了
CREATE TABLE `order`(……)

select id as “编号”,`name` as "姓名” from t_stu;# 起别名时,as 可以省略
select id as 编号,`name` as 姓名 from t_stu; # 如果字段名中没有空格,可以省略“”
select id as 编号,`name` as 姓 名 from t_stu; # 错误,如果字段名中有空格,不可以省略“”

2.2.5 数据导入指令

方式一:在命令行客户端登录MySQL,使用sorce指令导入

mysql> source d:\mysqldb.sql

方式二:基于具体的图形化界面的工具可以导入数据
如:SQLYog中,选择“工具”—“执行SQL脚本”—“选择xxx.sql文件,执行”

2.3基本select 语句

  • 最基本查询语句
SELECT 1;没有任何子句
SELECT 9/2;没有任何子句

2.3.1SELECT…FROM

  • 语法
SELECT 标识选择哪些列
FROM 标识从哪个表中选择
  • 选择全部列:
SELECT * 
FROM departments;
  • 一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符 “*”。通配符虽然可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。通配符的优势当不知所需要的列名称的时候,可以通过它获取

  • 生产环境下,不推荐直接使用select * 进行查询。

  • 选择特定的列

SELECT department_id, loaction_id
FROM departements;
  • MySQL中的SQL语句是不区分大小写的,因此SELECT和select的作用是相同的,但是,许多开发人员习惯将关键字大写、数据列和表名小写,读者也应该养成一个良好的编程习惯,这样写出来的代码更容易阅读和维护。

2.3.2列的别名

  • 重命名一个列
  • 便于计算
  • 紧跟列名,也可以在列名和别名之间加入关键字AS,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。
  • 关键字AS可以省略
  • 建议别名简单,见名知意
  • 例如:
SELECT last_name AS name,commission_pct comm
FROM employees;

2.3.3去除重复行

  • 默认情况下,查询会返回全部行,包括重复行
SELECT department_id
FROM employees;
  • 在SELECT语句中使用DISTINCT去除重复行
SELECT DISTINCT department_id
FROM employees;
  • 针对于:
SELECT DISTINCT department_id,salary
FROM employees;
  • 俩点注意:
    • DISTINCT需要放到所有列名的前面,如果写成SELECT salary,DISTINCT department_id From employees 会报错
    • DISTINCT其实是对后面所有列名的组合去重

2.3.4空值参与运算

  • 所有运算符或列值遇到null值,运算的结果为null
SELECT employee_id,salary,commission_pct,12 * salary * (1 + commission_pct) "annual_sal" 
FROM employees;
  • 这里你一定要注意,在 MySQL 里面, 空值不等于空字符串。一个空字符串的长度是 0,而一个空值的长度是空。而且,在 MySQL 里面,空值是占用空间的。

2.3.5 着重号

  • 错误的
mysql> SELECT * FROM ORDER;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right
syntax to use near 'ORDER' at line 1
  • 真确的
mysql> SELECT * FROM `ORDER`; 
+----------+------------+
| order_id | order_name 
| +----------+------------+
| 1 | shkstart | 
| 2 | tomcat |
 | 3 | dubbo |
  +----------+------------+
3 rows in set (0.00 sec) 
mysql> SELECT * FROM `order`;
 +----------+------------+
| order_id | order_name |
 +----------+------------+
| 1 | shkstart | 
| 2 | tomcat | 
| 3 | dubbo | 
+----------+------------+
3 rows in set (0.00 sec)
  • 结论
  • 我们需要保证表中的字段、表名等没有和保留字、数据库系统或常用方法冲突。如果真的相同,请在SQL语句中使用一对``(着重号)引起来。

2.4 显示表结构

  • 使用DESCRIBE或者DESC命令,表示表结构
DESCRIBE employees;DESC employees;
mysql> desc employees; 
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra | 
+----------------+-------------+------+-----+---------+-------+
| employee_id | int(6) | NO | PRI | 0 | |
| first_name | varchar(20) | YES | | NULL | | 
| last_name | varchar(25) | NO | | NULL | |
| email | varchar(25) | NO | UNI | NULL | |
| phone_number | varchar(20) | YES | | NULL | | 
| hire_date | date | NO | | NULL | | 
| job_id | varchar(10) | NO | MUL | NULL | |
| salary | double(8,2) | YES | | NULL | | 
| commission_pct | double(2,2) | YES | | NULL | | 
| manager_id | int(6) | YES | MUL | NULL | |
| department_id | int(4) | YES | MUL | NULL | | 
+----------------+-------------+------+-----+---------+-------+
11 rows in set (0.00 sec)
  • 其中各个字段含义分别解释如下:
  • Field:表示字段名称
  • Type:表示字段类型,
  • Null:表示该列是否可以存储NULL值
  • Key:表示该类是否已编制索引,PRI表示该列是主键的一部分,UNI表示该列是UNIQUE索引的一部分,MUL表示列中某个给定值允许多次出现
  • Default:表示该列是否有默认值,如果有,那么值多少
  • Extra:表示可以获取的与给定列有关的附加信息,例如:AUTO_INCREMENT等

2.5过滤数据

  • 语法
SELECT 字段1,字段2
FROM 表名
WHERE 过滤条件
  • 使用WHERE 子句,将不能满足条件的行过滤掉

  • WHERE子句紧随FROM子句

  • 例子:查询部门id=90 的

SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE department_id=90;

3.运算符

3.1 算术运算符

  • 算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加(+)、减(-)、乘(*)、除(/)和取模(%)运算。
    MySQL学习笔记-基础篇1_第40张图片- 加法与减法运算符
    MySQL学习笔记-基础篇1_第41张图片

  • 由运算结果可以得出如下结论

  • 一个整数类型的值对整数进行加法和减法操作,结果还是一个整数;

  • 一个整数类型的值对浮点数进行加法和减法,结果是一个浮点数

  • 加法和减法的优先级相同,进行先加后减操作与进行先减后加操作结果一样

  • 在java中,+ 的左右两边如果都是字符串,那么表示字符串的拼接,但是在MySQL中+只表示数值相加,如果遇到非数值类型,先尝试转成数值,如果转失败,按照0计算(补充:MySQL中字符串拼接要使用字符串函数CONCAT()实现)

  • 乘法与除法运算
    MySQL学习笔记-基础篇1_第42张图片- 由运算结果可以得出下面结论

  • 一个数乘以整数1和除以整数1仍然是原数

  • 一个数乘以浮点数1和除以浮点数1后变成浮点数,数值与原数相等;

  • 一个数除以整数后,不管是否能除尽,结果都为一个浮点数;

  • 一个数除以另一个数,除不尽时,结果为一个浮点数,并保留到小数点后4位;

  • 乘法和除法的优先级相同,进行先乘后除操作与先除后乘操作,得出的结果相同。

  • 在数学运算中,0不能用作除数,在MySQL中,一个数除以0为NULL。

  • 求模(求余)运算符
    MySQL学习笔记-基础篇1_第43张图片
    可以看到,100对3求模后的结果为3,对5求模后的结果为0。

3.2 比较运算符

比较运算符用来对表达式左边的操作数和右边的操作数进行比较,比较的结果为真则返回1,比较的结果为假则返回0,其他情况则返回NULL。
比较运算符经常被用来作为SELECT查询语句的条件来使用,返回符合条件的结果记录。
MySQL学习笔记-基础篇1_第44张图片

  • 等号运算符
  • 等号运算符(=)判断等号两边的值、字符串或表达式是否相等,如果相等则返回1,不相等则返回0。
  • 在使用等号运算符时,遵循如下规则:
    • 如果等号两边的值、字符串或表达式都为字符串,则MySQL会按照 字符串进行比较,其比较的是每个字符串中字符的ANSI编码是否相等。
    • 如果等号两边的值都是整数,则MySQL会按照整数来比较俩个值的大小。
    • 如果等号两边的值,以故事整数,另一个是字符串,则MySQL会将字符串转化为数字进比较。
    • 如果等号两边的值、字符串或表达式中有一个位NULL,则比较结果为NULL。

对比:SQL中赋值符号使用(:=)
MySQL学习笔记-基础篇1_第45张图片- 安全等于运算符

  • 安全等于运算符(<=>)与等于运算符(=)的作用是相似的, 唯一的区别 是‘<=>’可
    以用来对NULL进行判断。在两个操作数均为NULL时,其返回值为1,而不为NULL;当一个操作数为NULL时,其返回值为0,而不为NULL。
    MySQL学习笔记-基础篇1_第46张图片
    可以看到,使用安全等于运算符时,两边的操作数的值都为NULL时,返回的结果为1而不是NULL,其他返回结果与等于运算符相同。

  • 不等于运算符

  • 不等于运算符(<>和!=)用于判断两边的数字、字符串或者表达式的值是否不相等,
    如果不相等则返回1,相等则返回0。不等于运算符不能判断NULL值。如果两边的值有任意一个为NULL,或两边都为NULL,则结果为NULL。 SQL语句示例如下:
    MySQL学习笔记-基础篇1_第47张图片

  • 非符号类型运算符
    在这里插入图片描述MySQL学习笔记-基础篇1_第48张图片

  • 空运算符

  • 空运算符(IS NULL或者ISNULL)判断一个值是否为NULL,如果为NULL则返回1,否则返回
    0。 SQL语句示例如下:
    MySQL学习笔记-基础篇1_第49张图片

  • 非空运算符

  • 非空运算符(IS NOT NULL)判断一个值是否不为NULL,如果不为NULL则返回1,否则返
    回0。 SQL语句示例如下:
    MySQL学习笔记-基础篇1_第50张图片MySQL学习笔记-基础篇1_第51张图片- 最小值运算符

  • LEAST(值1,值2,……,值n)。其中值n表示参数列表中有n个值,在有多个参数的情况下,返回最小值、

MySQL学习笔记-基础篇1_第52张图片

  • 由结果可以看到,当参数是整数或者浮点数时,LEAST将返回其中最小的值;当参数为字符串时,返回字母表中顺序最靠前的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

  • 最大值运算符

  • 语法格式为:GREATEST(值1,值2,…,值n)。其中,n表示参数列表中有n个值。当有两个或多个参数时,返回值为最大值。假如任意一个自变量为NULL,则GREATEST()的返回值为NULL。

  • MySQL学习笔记-基础篇1_第53张图片

  • 由结果可以看到,当参数中是整数或者浮点数时,GREATEST将返回其中最大的值;当参数为字符串时,返回字母表中顺序最靠后的字符;当比较值列表中有NULL时,不能判断大小,返回值为NULL。

  • BETWEEN AND运算符

  • BETWEEN运算符使用的格式通常为SELECT D FROM TABLE WHERE C BETWEEN A AND B,此时,当C大于或等于A,并且C小于或等于B时,结果为1,否则结果为0。

MySQL学习笔记-基础篇1_第54张图片- IN运算符

  • IN运算符用于判断给定的值是否是IN列表中的一个值,如果是则返回1,否则返回0。如果给
    定的值为NULL,或者IN列表中存在NULL,则结果为NULL。
    MySQL学习笔记-基础篇1_第55张图片在这里插入图片描述
  • NOT IN运算符
  • NOT IN运算符用于判断给定的值是否不是IN列表中的一个值,如果不是IN列表中的一
    个值,则返回1,否则返回0。
    MySQL学习笔记-基础篇1_第56张图片- **LIKE运算符 **
  • LIKE运算符主要用来匹配字符串,通常用于模糊匹配,如果满足条件则返回1,否则返回 0。如果给定的值或者匹配条件为NULL,则返回结果为NULL。
  • LIKE运算符通常使用如下通配符:
"%":匹配0个或多个字符
"_":只能匹配一个字符

MySQL学习笔记-基础篇1_第57张图片- ESCAPE

  • 回避特殊符号的:使用转义符。例如:将[%]转为[ %]、[]转为[ ],然后再加上[ESCAPE‘$’]即可。

  • 在这里插入图片描述

  • 如果使用\表示转义,要省略ESCAPE。如果不是\,则要加上ESCAPE。
    在这里插入图片描述

  • REGEXP运算符

  • REGEXP运算符用来匹配字符串,语法格式为: expr REGEXP 匹配条件 。如果expr满足匹配条件,返回1;如果不满足,则返回0。若expr或匹配条件任意一个为NULL,则结果为NULL。

  • REGEXP运算符在进行匹配时,常用的有下面几种通配符
    (1)‘^’匹配以该字符后面的字符开头的字符串。
    (2)‘$’匹配以该字符前面的字符结尾的字符串。
    (3)‘.’匹配任何一个单字符。
    (4)“[…]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”或“b”或“c”。为了命名字符的范围,使用一 个‘-’。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
    (5)‘*’匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的‘x’字符,“[0-9]*”匹配任何数量的数字, 而“*”匹配任何数量的任何字符。

  • SQL语句示例如下:
    MySQL学习笔记-基础篇1_第58张图片

3.3逻辑运算符

  • 逻辑运算符主要用来判断表达式的真假,在MySQL中,逻辑运算符的返回结果为1,0或NULL。
  • MySQL中支持四种逻辑运算符如下:
    MySQL学习笔记-基础篇1_第59张图片
  • 逻辑非运算符
  • 逻辑非(NOT 或!)运算符表示当给定值为0 时返回1,当给定值值为非0值时返回0,当给定值为NULL时返回NULL。

MySQL学习笔记-基础篇1_第60张图片在这里插入图片描述

  • 逻辑与运算符
  • 逻辑与(AND或&&)运算符是当给定值的所有值均为非0值,并且都不为NULL时,返回值1;当给定的一个值或多个值为0时则返回0;否则返回NULL。

MySQL学习笔记-基础篇1_第61张图片

  • 逻辑或运算符
  • 逻辑或(OR或II)运算符是给定的值都不为NULL,并且任何一个值为非0值时,则返回1,否则返回0;当一个值为NULL,并且另一个值为非0时,返回1,否则返回NULL;当俩个值都为NULL,返回NULL。
    MySQL学习笔记-基础篇1_第62张图片
  • 注意:OR可以和AND一起使用,但是在使用时要注意两者的优先级,由于AND的优先级高于OR,因此先对AND两边的操作数进行操作,再与OR中的操作数结合。

-逻辑异或运算符

  • 逻辑异或(XOR)运算符是当给定的值中任意一个值为NULL时,则返回NULL,如果两个非NULL的值都为0或者都不等于0,则返回0,如果一个值为0,另一个值不为0,则返回1.
    MySQL学习笔记-基础篇1_第63张图片

3.4 位运算符

位运算符是在二进制数上进行计算的运算符。位运算符会先将操作数变成二进制,然后进行为运算,最后将计算结果从二进制转换成十进制。

  • MySQL支持的位运算符如下:

MySQL学习笔记-基础篇1_第64张图片

  • 按位与运算符

  • 按位与(&)运算符将给定值对应的二进制数逐位进行逻辑与运算,当给定值对应的二进制位的数值都为1是,则该位返回1,否则返回0。
    MySQL学习笔记-基础篇1_第65张图片

  • 1的二进制数为0001,10的二进制数为1010,所以1 & 10的结果为0000,对应的十进制数为0。20的二进制数为10100,30的二进制数为11110,所以20 & 30的结果为10100,对应的十进制数为20。

  • 按位或运算符

  • 按位或(|)运算符将给定的值对应的二进制数逐位进行逻辑或运算。当给定值对应的二进制位的数值有一个或两个为1时,则该为返回1,否则返回0。
    在这里插入图片描述1的二进制数为0001,10的二进制数为1010,所以1 | 10的结果为1011,对应的十进制数为11。20的二进制数为10100,30的二进制数为11110,所以20 | 30的结果为11110,对应的十进制数为30。

  • 按位异或运算符

  • 按位异或(^)运算符将给定的值对应的二进制数逐位进行逻辑异或运算。当给定值
    对应的二进制位的数值不同时,则该位返回1,否则返回0。
    MySQL学习笔记-基础篇1_第66张图片1的二进制数为0001,10的二进制数为1010,所以1 ^ 10的结果为1011,对应的十进制数为11。20的二进制数为10100,30的二进制数为11110,所以20 ^ 30的结果为01010,对应的十进制数为10。

  • 按位取反运算符

  • 按位取反(~)运算符将给定的值的二进制数逐位进行取反操作,即将1变为0,将0变 为1。
    MySQL学习笔记-基础篇1_第67张图片
    由于按位取反(~)运算符的优先级高于按位与(&)运算符的优先级,所以10 & ~1,首先,对数字1进行按位取反操作,结果除了最低位为0,其他位都为1,然后与10进行按位与操作,结果为10。

  • 按位右移运算符

  • 按位右移(>>)运算符将给定的值的二进制数的所有位右移指定的位数。右移指定的位数后,右边低位的数值被移出并丢弃,左边高位空出的位置用0补齐。
    MySQL学习笔记-基础篇1_第68张图片

  • 1的二进制数为0000 0001,右移2位为0000 0000,对应的十进制数为0。4的二进制数为0000 0100,右移2位为0000 0001,对应的十进制数为1。

  • 按位左移运算符

  • 按位左移(<<)运算符将给定的值的二进制数的所有位左移指定的位数。左移指定的位数后,左边高位的数值被移出并丢弃,右边低位空出的位置用0补齐。
    MySQL学习笔记-基础篇1_第69张图片1的二进制数为0000 0001,左移两位为0000 0100,对应的十进制数为4。4的二进制数为0000 0100,左移两位为0001 0000,对应的十进制数为16。

3.5 运算符的优先级

MySQL学习笔记-基础篇1_第70张图片

  • 数字编号越大,优先级越高,优先级高的运算符先进行计算。可以看到,复制运算符的优先级最低,使用“()”括起来的表达式的优先级最高。

3.6 拓展:使用正则表达式查询

  • 正则表达式通常被用来检索或替换那些符合某个模式的文本内容,根据指定的匹配模式匹配文本中符合要求的特殊字符串。
  • 例如,从一个文本文件中提取电话号码,查找一篇文章中重复的单词或者替换用户输入的某些敏感词语等,这些地方都可以使用正则表达式。正则表达式强大而且灵活,可以应用于非常复杂的查询。
  • MySQL中使用REGEXP关键字指定正则表达式的字符匹配模式。下表列出了REGEXP操作符中常用字符匹配列表。
    MySQL学习笔记-基础篇1_第71张图片
  • 查询以特定字符或字符串开头的记录
  • 字符串“^”匹配以特定字符或者字符串开头的文本,在fruits表中,查询f_name 字段以字母“b”开头的记录,SQL如下:
SELECT * FROM fruits WHERE f_name REGEXP '^b';
  • 查询以特定字符或字符串结尾的记录
  • 字符“$”匹配以特定字符或字符串结尾 文本。在fruits表中查询f_name字段以字母“y”结尾的记录,SQL如下:
SELECT * FROMfruits WHERE f_name REGEXP 'y$';
  • 用符号"."来替代字符串中的任意一个字符 字符
  • ‘.’匹配任意一个字符。 在fruits表中,查询f_name字段值包含字母‘a’与‘g’且两个字母之间只有一个字母的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP 'a.g';
  • 使用"*“和”+"来匹配多个字符
  • 星号‘*’匹配前面的字符任意多次,包括0次。加号‘+’匹配前面的字符至少一次。在fruits表中,查询f_name字段值以字母‘b’开头且‘b’后面出现字母‘a’的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP '^ba*';
  • 在fruits表中,查询f_name字段值以字母‘b’开头且‘b’后面出现字母‘a’至少一次的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP '^ba+';
  • 匹配指定字符串
  • 正则表达式可以匹配指定字符串,只要这个字符串在查询文本中即可,如要匹配多个字符串,多个字符串之间使用分隔符‘|’隔开。在fruits表中,查询f_name字段值包含字符串“on”的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP 'on';
  • 在fruits表中,查询f_name字段值包含字符串“on”或者“ap”的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP 'on|ap';
  • LIKE运算符也可以匹配指定的字符串,但与REGEXP不同,LIKE匹配的字符串如果在文本中间出现,则找不到它,相应的行也不会返回。REGEXP在文本内进行匹配,如果被匹配的字符串在文本中出现,REGEXP将会找到它,相应的行也会被返回。

  • 匹配指定字符中的任意一个

  • 方括号“[]”指定一个字符集合,只匹配其中任何一个字符,即为所查找的文本。在fruits表中,查找f_name字段中包含字母‘o’或者‘t’的记录,SQL语句如下:

SELECT * FROM fruits WHERE f_name REGEXP '[ot]';
  • 在fruits表中,查询s_id字段中包含4、5或者6的记录,SQL语句如下:
SELECT * FROM fruits WHERE s_id REGEXP '[456]';
  • 匹配指定字符以外的字符
  • “[^字符集合]” 匹配不在指定集合中的任何字符。在fruits表中,查询f_id字段中包含字母ae和数字12以外字符的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_id REGEXP '[^a-e1-2]';
  • 使用{n,}或者{n,m}来指定字符串连续出现的次数
  • “字符串{n,}”表示至少匹配n次前面的字符;“字符串{n,m}”表示匹配前面的字符串不少于n次,不多于m次。例如,a{2,}表示字母a连续出现至少2次,也可以大于2次;a{2,4}表示字母a连续出现最少2次,最多不能超过4次。在fruits表中,查询f_name字段值出现字母‘x’至少2次的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP 'x{2,}';
  • 在fruits表中,查询f_name字段值出现字符串“ba”最少1次、最多3次的记录,SQL语句如下:
SELECT * FROM fruits WHERE f_name REGEXP 'ba{1,3}';

4.排序与分页

4.1 排序数据

  • 排序规则
  • 使用ORDER BY 子句排序
    • ASC(ascend):升序
    • DESC(descend):降序
  • ORDER BY 子句在SELECT语句的结尾。
  • 单列排序
SELECT last_name, job_id, department_id, hire_date 
FROM employees
ORDER BY hire_date;

MySQL学习笔记-基础篇1_第72张图片

  • ** 多列排序**
SELECT last_name, department_id, salary 
FROM employees
ORDER BY department_id, salary DESC;

MySQL学习笔记-基础篇1_第73张图片

  • 可以使用不在SELECT列表中的列排序
  • 在对多列进行排序时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序,如果第一列数据中所有值都是唯一的,将不在对第二列进行排序。

4.2 分页

  • 场景:
    • 查询返回的记录太多了,查看起来很不方便,怎么样能够实现分页查询呢?
    • 表里有4条数据,只想要显示第2,3两条数据怎么办?
  • 实现规则
  • 分页原理
    • 所谓的分页显示,就是将数据库中的结果集,一段一段显示出来需要的条件。
    • MySQL中使用LIMIT 实现分页
  • 格式
LIMIT [位置偏移量,]行数

第一个“位置偏移量”参数指示MYSQL从哪一行开始显示,是一个可选参数,如果不指定“位置偏移量”,将会从表中的第一条记录开始(第一条记录的位置偏移量是0,第二条的位置偏移量是1,以此类推);第二个参数“行数”指示返回的记录条数。

  • 举例
-- 前10条记录:
SELECT * FROM 表名 LIMIT 0,10;
-- 或 
SELECT * FROM 表名 LIMIT 10;
-- 第11 条至第20条
SELECT * FROM 表名 LIMIT 10,10;

  • MySQL 中可以使用“LIMIT 3 OFFSET 4”,意思是获取从第五条记录开始后面的3条记录,和“LIMIT 4,3;”返回结果一样。

  • 分页显示公式:(当前页数-1) 每页条数,每页条数*

SELECT * FROM table
LIMIT (PageNo-1)*PageSize,PageSize;
  • 注意:LIMIT子句必须放在整个SELECT 语句的最后!

  • 使用LIMIT的好处:

    • 约束返回结果的数量可以减少数据表的网络传输量,也可以提升查询效率。如果我们知道返回结果只有1条,就可以使用LIMIT 1,告诉SELECT语句只需要返回一条记录即可,这样的好处是SELECT不需要扫描完整张表,只需要检索到一条符合条件的记录返回即可。
  • 拓展

  • 在不同的 DBMS 中使用的关键字可能不同。在 MySQL、PostgreSQL、MariaDB 和 SQLite 中使用 LIMIT 关键字,而且需要放到 SELECT 语句的最后面。

  • 在不同的DBMS中使用的关键字可能不同,在MYSQL、PostgreSQL、MariaDB 和 SQLite 中使用 LIMIT 关键字,而且需要放到 SELECT 语句的最后面。

  • 如果是SQL Server 和Access,需要使用TOP 关键字,比如:

SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC;
  • 如果是DB2 ,使用FETCH FIRST 5 ROWS ONLY这样的关键字:
SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY;
  • 如果是Oracle ,需要基于ROWNUM来统计行数:
SELECT rownum, last_name,salary FROM employees WHERE rownum<5 ORDER BY salary DESC;
  • 需要说明,这条语句是先取出前5条数据行,然后再按照hp_max从高到低的顺序进行排序,但是这样的结果和上述方法的并不一样,可以使用子查询(后面学习)
SELECT rownum,last_name,salary
FROM (
	SELECT last_name,salary
	FROM employees
	ORDER BY salary DESC)
WHERE rownum<10;

5 .多表查询

  • 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。
  • 前提条件:这些一起查询的表之间是有关系的(一对一,一对多),它们之间的一定有关联字段,这个关联字段可能建立了外键,也可能没有建立外键。比如员工表和部门表,这两个表依靠“部门编号”进行关联

5.1 一个案例引发的多表连接

5.1.1 案例说明

MySQL学习笔记-基础篇1_第74张图片

  • 从多个表中获取数据:
    MySQL学习笔记-基础篇1_第75张图片
-- 案例:查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments;

MySQL学习笔记-基础篇1_第76张图片
MySQL学习笔记-基础篇1_第77张图片

  • 分析情况:会产生笛卡尔积的错误

5.1.2 笛卡尔积(或交叉连接)的理解

笛卡尔乘积是一个数学运算。假设有俩个集合X和Y,那么X和Y的笛卡尔积就是X和Y的所有可能组合,也就是一个对象来自X,一个对象来自Y的所有可能。组合的个数即为两个集合中元素的个数乘积。
MySQL学习笔记-基础篇1_第78张图片

  • SQL92中,笛卡尔积也称为交叉连接,英文是CROSS JOIN。在SQL99中也是使用CROSS JOIN 表示交叉连接。它的作用就是可以把任意表进行连接,即使这俩张表不相关。在MYSQL中如下情况会出现笛卡尔积:
# 查询员工姓名和所在部门名称
SELECT last_name, department_name FROM employees, departments;
SELECT last_name, department_name FROM employees CROSS JOIN departments;
SELECT last_name, department_name FROM employees INNER JOIN departments;
SELECT last_name, department_name FROM employees JOIN departments; 

5.1.3案例分析与问题解决

  • 笛卡尔积的错误会在下面条件下产生
    • 省略多个表的连接条件
    • 连接条件(或关联条件)无效
    • 所有表中的所有行相互连接
  • 为了避免笛卡尔积,可以在WHERE 加入有效的连接条件
  • 加入连接条件后,查询语法
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column = table2.column;	# 连接条件
  • 在WHERE 子句中写入连接条件。
  • 正确写法:
-- 查询员工的姓名及其部门名称
SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
  • 在表中有相同列时,在列名之前加上表名前缀

5.2 多表查询分类讲解

  • 分类1:等值连接VS非等值连接
  • 等值连接
    MySQL学习笔记-基础篇1_第79张图片
SELECT employees.employee_id, employees.last_name,
	employees.department_id, departments.department_id,departments.location_id
FROM employees, departments
WHERE employees.department_id = departments.department_id;

MySQL学习笔记-基础篇1_第80张图片

  • 拓展1:多个连接条件与AND操作符
  • 拓展2:区分重复的列名
    • 多个表中有相同的列时,必须在列名之前加上表名前缀。
    • 在不同表中具有相同列名的列可以用表名加以区分。
SELECT employees.last_name, departments.department_name,employees.department_id
FROM employees,departments
WHERE employees.department_id = departments.department_id;
  • 拓展3:表的别名
    • 使用别名可以简化查询
    • 列名前使用表名前缀可以提高查询效率。
SELECT e.employee_id, e.last_name, e.department_id,
	d.department_id, d.location_id
FROM employees e, departments d
WHERE e.department_id = d.department_id;
  • 注意:如果我们使用了表的别名,在查询字段中、过滤条件中就只能使用别名进行代替,不能使用原有的表名,否则就会报错。
阿里开发规范:
【强制】对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名钱加上表的别名
(或表名)进行限定。
说明:对多表进行查询记录、更新记录、删除记录时,如果对操作列没有限定表的别名(或表名),
并且操作列在多个表中存在时,会抛出异常。
  • 拓展4:连接多个表
    MySQL学习笔记-基础篇1_第81张图片

  • 总结:连接n个表,至少需要n-1个连接条件

  • 非等值连接
    MySQL学习笔记-基础篇1_第82张图片

SELECT  e.last_name, e.salary, j.grade_level
FROM employees, job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;

MySQL学习笔记-基础篇1_第83张图片

  • ** 分类2:自连接VS非自连接**

MySQL学习笔记-基础篇1_第84张图片- 当table1 和table2本质上是同一张表,只是用取别名的方式虚拟成两张表以代表不同的意义,然后两张表再进行内连接,外连接等查询。

  • 题目:查询employee是 表,返回 Xxx works for Xxx
SELECT CONCAT(worker.last__name, 'works for' ,manager.last_name)
FROM employees worker, employees manager
WHERE worker.manager_id = manager.employee_id;
  • ** 分类3:内连接VS外连接**

  • 除了查询满足条件的记录外,外连接还可以查询某一方不满足条件的记录。
    MySQL学习笔记-基础篇1_第85张图片

  • 内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另外一个表不匹配的行

  • 外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。

  • 如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表

  • 如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表

  • SQL92:使用(+)创建连接

  • 在 SQL92 中采用(+)代表从表所在的位置。即左或右外连接中,(+) 表示哪个是从表。

  • Oracle 对 SQL92 支持较好,而 MySQL 则不支持 SQL92 的外连接。

-- 左外连接
SELECT last_name,department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id(+);

-- 右外连接
SELECT last_name,department_name
FROM employees, departments
WHERE employees.department_id(+) = departments.department_id;
  • 在SQL92中,只有左外连接和右外连接,没有全外连接。

5.3 SQL99 语法实现多表查询

5.3.1 基本语法

  • 使用JOIN…ON子句创建连接的语法结构:
SELECT table1.column, table2.column, table3.column
FROM table1 
	JOIN table2 ON table1和table2的连接条件
		JOIN table3 ON table2 和table3的连接条件
  • SQL99采用这种嵌套结构非常清爽,层次性更强、可读性更强,即使再多的表进行连接也都清晰可见。
  • 语法说明:
    • 可以使用ON子句指定额外的连接条件。
    • 这个连接条件是与其它条件分开的
    • ON子句使语句具有更高的易读性
    • 关键字JOIN、INNER JOIN, CROSS JOIN的含义是一样的,都表示内连接。

5.3.2 内连接(INNER JOIN)的实现

  • 语法:
SELECT 字段列表
FROM 表A INNER JOIN 表B
ON 关联条件
WHERE 等其它子句;
  • 例子1
SELECT e.employee_id,e.last_name,e.department_id,d.department_id, d.location_id
FROM empolyees e JOIN departments d 
ON (e.department_id = d.department_id);

MySQL学习笔记-基础篇1_第86张图片

  • 例子2
SELECT employee_id, city, department_name
FROM employees e 
JOIN departments d 
ON d.department_id = e.department_id
JOIN locations l
ON d.location_id = l.location_id;

MySQL学习笔记-基础篇1_第87张图片

5.3.3 外连接(OUTER JOIN) 的实现

左外连接(LEFT OUTER JOIN)

  • 语法:
-- 实现查询结果是A
SELECT 字段列表
FROM A表 LEFT JOIN B表
ON 关联条件
WHERE等其它子句
  • 举例:
SELECT e.last_name, e.department_id, d.department_name
FROM employees e 
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id);

MySQL学习笔记-基础篇1_第88张图片
右外连接(RIGHT OUTER JOIN)

  • 语法:
-- 实现查询结果是B
SELECT 字段列表
FROM A表 RIGHT JOIN B表
ON 关联条件
WHERE 等其它子句
  • 举例:
SELECT  e.last_name, e.department_id,d.department_name
FROM  employees e
RIGHT OUTER JOIN  departments d
ON (e.department_id = d.department_id);

MySQL学习笔记-基础篇1_第89张图片- 需要注意的是:LEFT JOIN 和RIGHT JOIN 只存在于SQL99 及以后的标准中,在SQL92中不存在,只能用(+)表示

  • 满外连接(FULL OUTER JOIN)
  • 满外连接的结果= 左右表匹配的数据+左表没有匹配到的数据+右表没有匹配的数据。
  • SQL99 是支持慢外连接的,使用FULL JOIN 或FULL OUTER JOIN 来实现
  • 需要注意的是,MySQL 不支持 FULL JOIN ,但是可以使用LEFT JOIN UNION RIGTH JOIN代替。

5.4 UNION 的使用

  • 合并查询结果利用UNION 关键字,可以给出多条SELECT 语句,并将它们的结果组合成单个结果集合,合并时,两个表对应的列数和数据类型必须相同,并且相互对应。各个SELECT 语句之间使用UNION 或UNION ALL 关键字分隔。
SELECT column,... FROM table1
UNION [ALL]
SELECT column,... FROM table2;
  • UNION 操作符

MySQL学习笔记-基础篇1_第90张图片

  • UNION 操作符返回两个查询结果集的并集,去除重复记录

  • UNION ALL 操作符
    MySQL学习笔记-基础篇1_第91张图片

  • UNION ALL 操作符返回两个查询的结果集的并集,对两个结果集的重复部分,不去重

  • 举例:查询部门编号大于90 或邮箱包含a的员工信息

-- 方式一
SELECT * FROM employees WHERE email LIKE '%a%' OR department_id>90;

-- 方式二
SELECT * FROM employees WHERE email LIKE '%a%
UNION
SELECT * FROM employees WHERE department_id>90;
  • 举例:查询中国用户中男性的信息以及美国用户中年男性的用户信息
SELECT id, cname FROM t_chinamale WHERE csex='男'
UNION ALL
SELECT id, tname FROM t_usmale WHERE tGender='male';

5.5 7中SQL JOINS的实现

MySQL学习笔记-基础篇1_第92张图片

5.5.1代码实现

  • 中图:内连接 A ∩ B A \cap B AB
SELECT employee_id, last_name, department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;
  • 左上图:左外连接
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;
  • 右上图:右外连接
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;
  • 左中图: A − A ∩ B A-A \cap B AAB
SELECT  employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d 
ON e.department_id  = d.department_id
WHERE d.department_id IS NULL;
  • 右中图: B − A ∩ B B-A\cap B BAB
SELECT employee_id, last_name, department_name 
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;
  • 左下图:满外连接
  • 左上图+ 右上图 A ∪ B A\cup B AB
SELECT employee_id, last_name,department_name
FROM employees e LEFT JOIN departments d 
ON e.department_id  = d.department_id
WHERE d.department_id IS NULL 
UNION ALL # 没有去重操作,效率高
SELECT employee_id,last_name,department_name
FROM employees e RIGTH JOIN departments d
On e.department_id = d.department_id;
  • 右下图
  • 左中图 + 右中图 A ∪B- A∩B 或者 (A - A∩B) ∪ (B - A∩B)
SELECT employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT employee_id, last_name, department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;

5.5.2 语法格式小结

  • 左中图
  • 实现A - A∩B
select 字段列表
from A表 
left join B表 
on 关联条件
 where 从表关联字段 is null and 等其他子句;
  • 右中图
  • 实现B - A∩B
select 字段列表
from A表
right join B表 
on 关联条件 
where 从表关联字段 is null and 等其他子句;
  • 左下图
  • 实现查询结果是A∪B
  • 用左外的A,union 右外的B
select 字段列表
from A表 
left join B表 
on 关联条件 
where 等其他子句 
union 
select 字段列表
from A表 
right join B表 
on 关联条件 
where 等其他子句;
  • 右下图
  • 实现A∪B - A∩B 或 (A - A∩B) ∪ (B - A∩B)
  • 使用左外的 (A - A∩B) union 右外的(B - A∩B)
select 字段列表
from A表 
left join B表 
on 关联条件 
where 从表关联字段 is null and 等其他子句 
union 
select 字段列表
from A表 
right join B表 
on 关联条件 
where 从表关联字段 is null and 等其他子句

5.6 SQL99语法新特性

5.6.1 自然连接

SQL99 在SQL92的基础上提供了一些特殊的语法,比如NATURAL JOIN 用来表示自然连接,可以把自然连接为SQL92中的等值连接,它会自动查询俩张连接表中所有相同字段,然后进行等值连接。

  • 在SQL92标准中:
SELECT employee_id,last_name,department_name 
FROM employees e JOIN departments d 
ON e.`department_id` = d.`department_id` 
AND e.`manager_id` = d.`manager_id`;
  • 在SQL99中可以写成
SELECT employee_id,last_name,department_name 
FROM employees e NATURAL JOIN departments d;

5.6.2USING连接

  • 当进行连接的时候,SQL99 还支持使用USING连接指定数据表里的同名字段进行等值连接。但是只能配合JOIN一起使用。比如:
SELECT employee_id, last_name, department_name
FROM employees e JOIN departments d
USING(department_id);

与自然连接NATURAL JOIN 不同的是,USING指定了具体的相同的字段名称,需要在USING的括号()中填入要指定的同名字段,同时使用JOIN…USING 可以简化 JOIN ON 的等值连接,与下面的SQL查询结果相同

SELECT employee_id, last_name, department_name
FROM employees e, departments d
WHERE e.department_id = de.department_id;

5.7 小结

表连接的约束条件可以有三种方式:WHERE, ON, USING

  • WHERE:适用于所有关联查询
  • ON:只能和JOIN一起使用,只能写关联条件,虽然关联条件可以并到WHERE中和其他条件一起写,但是分开写可读性更好。
  • USING只能和JOIN一起使用,而且要求两个关联字段在关联表中名称一致,而且只能表示关联字段值相等。
#关联条件 
#把关联条件写在where后面 
SELECT last_name,department_name 
FROM employees,departments 
WHERE employees.department_id = departments.department_id; 

#把关联条件写在on后面,只能和JOIN一起使用 
SELECT last_name,department_name 
FROM employees INNER JOIN departments 
ON employees.department_id = departments.department_id; 

SELECT last_name,department_name 
FROM employees CROSS JOIN departments 
ON employees.department_id = departments.department_id; 

SELECT last_name,department_name 
FROM employees JOIN departments 
ON employees.department_id = departments.department_id; 
#把关联字段写在using()中,只能和JOIN一起使用 
#而且两个表中的关联字段必须名称相同,而且只能表示= #查询员工姓名与基本工资 
SELECT last_name,job_title 
FROM employees INNER JOIN jobs 
USING(job_id); 
#n张表关联,需要n-1个关联条件 
#查询员工姓名,基本工资,部门名称 
SELECT last_name,job_title,department_name 
FROM employees,departments,jobs 
WHERE employees.department_id = departments.department_id 
AND employees.job_id = jobs.job_id; 

SELECT last_name,job_title,department_name 
FROM employees INNER JOIN departments INNER JOIN jobs 
ON employees.department_id = departments.department_id 
AND employees.job_id = jobs.job_id;
  • 注意:要控制连接表的数量。多表连接相当于嵌套for循环应用,非常消耗资源,会让SQL查询性能下降得很严重,因此不要连接不必要的表,在许多DSMS中,也会有最大连接表的限制。

  • 【强制】超过三个表静止JOIN。需要JOIN的字段,数据类型保持绝对一致,多表关联查询是,保证被关联的字段需要有索引

  • 说明:即使双表JOIN也要注意表索引、SQL性能

  • 附录:常用SQL标准

  • 在正式开始讲连接表的种类时,我们首先需要知道 SQL 存在不同版本的标准规范,因为不同规范下的表连接操作是有区别的。

  • SQL 有两个主要的标准,分别是 SQL92 和 SQL99 。92 和 99 代表了标准提出的时间,SQL92 就是 92 年提出的标准规范。当然除了 SQL92 和 SQL99 以外,还存在 SQL-86、SQL-89、SQL:2003、SQL:2008、 SQL:2011 和 SQL:2016 等其他的标准。这么多标准,到底该学习哪个呢?

  • 实际上最重要的 SQL 标准就是 SQL92 和 SQL99。一般来说 SQL92 的形式更简单,但是写的 SQL 语句会比较长,可读性较差。而 SQL99 相比于 SQL92 来说,语法更加复杂,但可读性更强。我们从这两个标准发布的页数也能看出,SQL92 的标准有 500 页,而 SQL99 标准超过了1000 页。实际上从 SQL99 之后,很少有人能掌握所有内容,因为确实太多了。就好比我们使用Windows、Linux 和 Office 的时候,很少有人能掌握全部内容一样。我们只需要掌握一些核心的功能,满足日常工作的需求即可。

  • SQL92 和 SQL99 是经典的 SQL 标准,也分别叫做 SQL-2 和 SQL-3 标准。也正是在这两个标准发布之后,SQL 影响力越来越大,甚至超越了数据库领域。现如今 SQL 已经不仅仅是数据库领域的主流语言,还是信息领域中信息处理的主流语言。在图形检索、图像检索以及语音检索中都能看到 SQL 语言的使用。

6.单行函数

6.1函数的理解

6.1.1 什么是函数

  • 函数在计算机语言的使用中贯穿始终,函数的作用是什么呢?它可以把我们经常使用的代码封装起来,需要的时候直接调用即可。这样既 提高了代码效率 ,又 提高了可维护性 。在 SQL 中我们也可以使用函数对检索出来的数据进行函数操作。使用这些函数,可以极大地 提高用户对数据库的管理效率 。

MySQL学习笔记-基础篇1_第93张图片

  • 从函数定义的角度出发,将函数分成内置函数自定义函数。在SQL语言中,同样也包括了内置函数和自定义函数。内置函数是系统内置的通用函数,而自定义函数是根据自己的需要编写的。

6.1.2 不同DBMS函数的差异

  • 在使用SQL语言的时候,不是直接和这门语言打交道,而是通过它使用不同的数据库软件,即DBMS。DBMS之间的差异性很大,远大于同一个语言不同版本之间的差异。实际上,只有很少的函数是被BDMS同时支持的。比如在大多数DBMS使用(||)或者(+)来做拼接符,而在MySQL中的字符串拼接函数为CONCAT()。大部分DBMS会有自己特定的函数,这就意味着采用SQL函数的代码可移植性是很差的,因此在使用函数的时候需要特别注意。

6.1.3 MySQL 的内置函数及分类

MySQL提供了丰富的内置函数,这些函数使得数据的维护与管理更加方便,能够更好地提供数据的分析与统计功能,在一定程度上提高开发人员进行数据分析与统计的效率。

  • MySQL提供的内置函数从实现的功能角度可以分为数值函数、字符串函数、日期函数和时间函数、流程控制函数,加密与解密函数、获取MySQL信息函数、聚合函数等。这里将这些丰富的内置函数分为:单行函数、聚合函数(或分组函数)

  • 两种SQL函数
    MySQL学习笔记-基础篇1_第94张图片

  • 单行函数

  • 操作数据对象

  • 接收参数返回一个结果

  • 只对一行进行变换

  • 每行返回一个结果

  • 可以嵌套

  • 参数可以是一列或一个值

6.2 数值函数

6.2.1 基本函数

MySQL学习笔记-基础篇1_第95张图片

  • 举例:
SELECT
ABS(-123),ABS(32),SIGN(-23),SIGN(43),PI(),CEIL(32.32),CEILING(-43.23),FLOOR(32.32), FLOOR(-43.23),MOD(12,5)
FROM DUAL;

在这里插入图片描述

SELECT RAND(),RAND(),RAND(10),RAND(10),RAND(-1),RAND(-1) 
FROM DUAL;

在这里插入图片描述

SELECT 
ROUND(12.33),ROUND(12.343,2),ROUND(12.324,-1),TRUNCATE(12.66,1),TRUNCATE(12.66,-1) 
FROM DUAL;

在这里插入图片描述

6.2.2 角度与弧度互换函数

MySQL学习笔记-基础篇1_第96张图片

6.2.3 三角函数

MySQL学习笔记-基础篇1_第97张图片

  • 举例:
    ATAN2(M,N)函数返回两个参数的反正切值。 与ATAN(X)函数相比,ATAN2(M,N)需要两个参数,例如有两个点point(x1,y1)和point(x2,y2),使用ATAN(X)函数计算反正切值为ATAN((y2-y1)/(x2-x1)),使用ATAN2(M,N)计算反正切值则为ATAN2(y2-y1,x2-x1)。由使用方式可以看出,当x2-x1等于0时,ATAN(X)函数会报错,而ATAN2(M,N)函数则仍然可以计算。

ATAN2(M,N)函数的使用示例如下:

SELECT 
SIN(RADIANS(30)),DEGREES(ASIN(1)),TAN(RADIANS(45)),DEGREES(ATAN(1)),DEGREES(ATAN2(1,1) )
FROM DUAL;

在这里插入图片描述

6.2.4 指数与对数

MySQL学习笔记-基础篇1_第98张图片

6.2.5进制间的转换

MySQL学习笔记-基础篇1_第99张图片

6.3字符串函数

MySQL学习笔记-基础篇1_第100张图片MySQL学习笔记-基础篇1_第101张图片

  • 注意:MySQL中,字符串的位置是从1开始的。

  • 举例:
    MySQL学习笔记-基础篇1_第102张图片

6.4日期和时间函数

6.4.1获取日期、时间

MySQL学习笔记-基础篇1_第103张图片MySQL学习笔记-基础篇1_第104张图片

6.4.2日期与时间戳的转换

MySQL学习笔记-基础篇1_第105张图片
MySQL学习笔记-基础篇1_第106张图片MySQL学习笔记-基础篇1_第107张图片

6.4.3获取月份、星期、星期数、天数等函数

MySQL学习笔记-基础篇1_第108张图片MySQL学习笔记-基础篇1_第109张图片

6.4.4 日期的操作函数

MySQL学习笔记-基础篇1_第110张图片

6.4.5 时间和秒钟转换函数

MySQL学习笔记-基础篇1_第111张图片MySQL学习笔记-基础篇1_第112张图片

6.4.6 计算日期和时间的函数

MySQL学习笔记-基础篇1_第113张图片MySQL学习笔记-基础篇1_第114张图片MySQL学习笔记-基础篇1_第115张图片MySQL学习笔记-基础篇1_第116张图片MySQL学习笔记-基础篇1_第117张图片

6.4.7 日期的格式化与解析

MySQL学习笔记-基础篇1_第118张图片MySQL学习笔记-基础篇1_第119张图片MySQL学习笔记-基础篇1_第120张图片

6.5 流程控制

  • 流程处理函数可以根据不同的条件,执行不同的处理流程,可以在SQL语句中实现不同的条件选择。MySQL中的流程处理函数包括IF(),IFNULL(),CASE()

MySQL学习笔记-基础篇1_第121张图片MySQL学习笔记-基础篇1_第122张图片MySQL学习笔记-基础篇1_第123张图片

6.6 加密解密函数

  • 加密与解密函数主要用于对数据库中的数据进行加密和解密处理,以防止数据被他人窃取。这些函数在保证数据库安全时非常重要。

MySQL学习笔记-基础篇1_第124张图片

  • 可以看到,ENCODE(value,password_seed)函数与DECODE(value,password_seed)函数互为反函数

6.7 MySQL 信息函数

  • MySQL中内置了一些可以查询MySQL信息的函数,这些函数主要用于帮助数据库开发或运维人员更好地对数据库进行维护工作。
    MySQL学习笔记-基础篇1_第125张图片MySQL学习笔记-基础篇1_第126张图片

6.8 其他函数

  • MySQL 中有些函数无法对其进行具体的分类,但是这些函数在MySQL的开发和运维过程中也是不容忽视的。

MySQL学习笔记-基础篇1_第127张图片MySQL学习笔记-基础篇1_第128张图片MySQL学习笔记-基础篇1_第129张图片

7. 聚合函数

聚合函数是对一组数据进行汇总的函数,输入的是一组数据的集合,输入的是单个值

7.1 集合函数介绍

  • 什么是聚合函数
  • 聚合函数作用于一组数据,并对一组数据返回一个值

MySQL学习笔记-基础篇1_第130张图片

  • 聚合函数

    • AVG()
    • SUM()
    • MAX()
    • MIN()
    • COUNT()
  • 聚合函数语法

MySQL学习笔记-基础篇1_第131张图片

  • 聚合函数不能嵌套调用,比如不能出现类似“AVG(SUM(字段名))”形式的调用。

7.1.1AVG和SUM函数

可以对数值数据使用AVG和SUM函数

SELECT AVG(salary),MAX(salary),MIN(salary),SUM(salary)
FROM employees
WHERE job_id LIKE "%PEP%";

7.1.2 MIN 和MAX函数

  • 可以对任意数据类型的数据使用MIN和MAX函数
SELECT MIN(hire_date),MAX(hire_date)
FROM employees;

7.1.3 COUNT 函数

  • COUNT(*) 返回表中记录总数,适用于任意数据类型。
SELECT COUNT(*)
FROM employees 
WHERE department_id =50;
  • COUNT(expr)返回expr不为空的记录总数
SELECT COUNT(commission_pct)
FROM employees
WHERE department_id =50;
  • 问题1:用COUNT(*),COUNT(1),COUNT(列名)谁更好?

  • 其实,对于MyISAM引擎的表是没有区别的,这种引擎内部有一计数器在维护着行数。

  • Innodb引擎的表用COUNT(*),COUNT(1),直接读取行,复杂度O(n),因为Innodb真的要去数一遍。但好于具体的COUNT(列名)。

  • 能不能使用COUNT(列名)替代COUNT(*)?

  • 不要使用COUNT(列名)代替COUNT(*),COUNT(*)是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关

  • COUNT(*) 会统计值为NULL的行,而COUNT(列名) 不会统计此列为NULL值的行。

7.2 GROUP BY

7.2.1基本使用

MySQL学习笔记-基础篇1_第132张图片

  • 可以使用GROUP BY子句将表中的数据分成若干组
SELECT cloumn,group_function(cloumn)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY cloumn]
  • 明确:WHERE一定放在FROM后面

  • 在SELECT列表中所未包含在组函数中的列都应该包含在GROUP BY子句中

SELECT department_id,AVG(salary)
FROM employees 
GROUP BY department_id;

MySQL学习笔记-基础篇1_第133张图片- 包含在GROUP BY子句中的列不必包含在SELECT列表中

SELECT AVG(salary)
FROM employees
GROUP BY department_id;

MySQL学习笔记-基础篇1_第134张图片

7.2.2 使用多个列分组

MySQL学习笔记-基础篇1_第135张图片

SELECT department_id, dept_id, job_id,SUM(salary)
FROM employees 
GROUP BY department_id,job_id;

7.2.3 GROUP BY 中使用WITH ROLLUP

使用WITH ROLLUP 关键字后,在所有查询出的分组记录之后添加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量。

SELECT department_id,AVG(salary)
FROM employees
WHERE department_id>80
GROUP BY department_id WITH ROLLUP ;
  • 注意:当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是相互排斥的

7.3 HAVING

7.3.1 基本使用

MySQL学习笔记-基础篇1_第136张图片

  • 过滤分组:HAVING 子句
  • 行已经被分组
  • 使用了聚合函数
  • 满足HAVING 子句中条件的分组将被显示
  • HAVING不能单独使用,必须要跟GROUP BY一起使用
    MySQL学习笔记-基础篇1_第137张图片
SELECT department_id,MAX(salary)
FROM employees 
GROUP BY department_id
HAVING MAX(salary)>10000;

MySQL学习笔记-基础篇1_第138张图片

  • 非法使用聚合函数:不能在WHERE子句中使用聚合函数:如下
SELECT department_id,AVG(salary)
FROM employees 
WHERE AVG(salary)>8000
GROUP BY department_id;

MySQL学习笔记-基础篇1_第139张图片

7.3.2 WHERE 和HAVING对比

  • 区别1:WHERE可以直接使用表中的字段作为筛选条件,但不能使用分组中的计算函数作为筛选条件;HAVING必须要与GROUP BY配合使用,可以把分组计算的函数和分组字段作为筛选条件。

  • 这决定了,在需要对数据进行分组统计的时候,HAVING可以完成WHERE不能完成的任务,这是因为,在查询语法结构中,WHERE在GROUPBY之前,所以无法对分组结果进行筛选。HAVING 在GROUP BY之后,可以使用分组字段和分组中的计算函数,对分组的结果集进行筛选,这个功能是WHERE无法完成的。另外,WHERE排除的记录不在包括在分组中。

  • 区别2:如果需要通过连接从关联表中获取需要的数据,WHERE是先筛选后连接,而HAVING是先连接后筛选的

  • 这点,决定了在关联查询中,WHERE 比HAVING更高效。因为WHERE可以先筛选,用一个筛选后的较小数据集合关联表进行连接,这样占用的资源比较少,执行效率也比较高。HAVING则需要先把结果集准备好,也就是用未被筛选的数据集进行关联,然后对这个大的数据集进行筛选,这样占用的资源就比较多,执行效率也低。

  • 小结:
    MySQL学习笔记-基础篇1_第140张图片

  • 开发中选择

  • WHERE和HAVING也不是相互排斥的,可以在一个查询里面同时使用WHERE和HAVING。包含分组统计函数的条件用HAVING,普通条件用WHERE。这样就利用了WHERE条件的高效快速,又发挥了HAVING可使用包含分组统计函数的查询条件的优先。当 数据量特别大的时候,运行效率会有很大差别。

7.4 SELECT的执行过程。

7.4.1查询的结构

-- 方式一
SELECT .......
FROM ...,...,...
WHERE 多表的连接条件
AND 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ... ASC/DESC
LIMT ...,...

-- 方式二
SELECT ...,...,...
FROM ...JOIN ....
ON 多表连接条件
JOIN...
ON...
WHERE 不包含组函数的过滤条件
AND/OR 不包含组函数的过滤条件
GROUP BY ...,...
HAVING 包含组函数的过滤条件
ORDER BY ...ASC/DESC
LIMINT ...,...
----
-- 其中:
-- 1.FROM :从哪张表中筛选 
-- 2.ON:关联多表查询是,取出笛卡尔积
-- 3.WHERE:从表中筛选的条件
-- 4.GROUP BY:分组依据
-- 5.HAVING:在统计结果中再次筛选
-- 6.ORDER BY:排序
-- 7.LIMIT:分页

7.4.2 SELECT 执行顺序

需要记住SELECT查询时的俩个顺序:

  • 1.关键字的顺序是不能颠倒的:
SELECT ... FROM ... WHERE ...GROUP BY ...HAVING ...ORDER BY ... LIMINT ...
  • 2.SELECT 语句的执行顺序(在MySQL和Oracle中,SELECT执行顺序基本相同)

MySQL学习笔记-基础篇1_第141张图片

  • 比如写了一个SQL语句,那么关键字顺序和执行顺序如下:
SELECT DISTINCT player_id,player_name,count(*) as num #顺序5
FROM player JOIN team ON player.team_id = team.team_id  #顺序1
WHERE height>1.80  # 顺序2
GROUP BY player.team_id   #顺序3
HAVING num>2 #顺序4
ORDER BY num DESC #顺序 6
LIMIT 2 #顺序7

在SELECT语句执行这些步骤时候,每个步骤都会产生一个虚拟表,然后将这个虚拟表传入下一个步骤中作为输入。需要注意的是,这些步骤隐含在SQL的执行过程中,对我们来说是不可见的。

7.4.3SQL的执行原理

SELECT 是首先执行FROM这一步的,在这个阶段,如果是多张表联合查询,会经历下面几个步骤:

  • 1.首先通过CROSS JOIN求笛卡尔积,相当于得到虚拟表vt(virtual table)1-1;
  • 2.通过ON进行筛选在虚拟表vt1-1 的基础上进行筛选,得到虚拟表vt1-2;
  • 添加外部行。如果在使用的是左右连接或者是全连接,就会涉及到外部行,也就是在虚拟表vt1-2的基础上增加外部行,得到蓄力表vt1-3

当如果操作的是两张以上的表,还会重复上面的步骤,直到所有表都被处理完为止。这个过程得到是我们的原始数据。

  • 当我们拿到了查询数据表的原始数据,也就是最终的虚拟表 vt1 ,就可以在此基础上再进行 WHERE 阶 段 。在这个阶段中,会根据 vt1 表的结果进行筛选过滤,得到虚拟表 vt2 。然后进入第三步和第四步,也就是 GROUP 和 HAVING 阶段 。在这个阶段中,实际上是在虚拟表 vt2 的基础上进行分组和分组过滤,得到中间的虚拟表 vt3 和 vt4 。当我们完成了条件筛选部分之后,就可以筛选表中提取的字段,也就是进入到 SELECT 和 DISTINCT 阶段 。首先在 SELECT 阶段会提取想要的字段,然后在 DISTINCT 阶段过滤掉重复的行,分别得到中间的虚拟表vt5-1 和 vt5-2 。当我们提取了想要的字段数据之后,就可以按照指定的字段进行排序,也就是 ORDER BY 阶段 ,得到虚拟表 vt6 。最后在 vt6 的基础上,取出指定行的记录,也就是 LIMIT 阶段 ,得到最终的结果,对应的是虚拟表vt7 。当然我们在写 SELECT 语句的时候,不一定存在所有的关键字,相应的阶段就会省略。同时因为 SQL 是一门类似英语的结构化查询语言,所以我们在写 SELECT 语句的时候,还要注意相应的关键字顺序,所谓底层运行的原理,就是我们刚才讲到的执行顺序。

你可能感兴趣的:(学习记录,数据库概述与MySQL安装,基本SELECT语句,运算符与排序分页,多表查询,单行函数与聚合函数)