MySQL学习笔记

数据库基础知识

先谈发音
MySQL如何发音?在国内MySQL发音有很多种,Oracle官方文档说
他们念作
My sequal['si:kwəl]。

image-20220110135408948

数据库基本概念

1 数据
数据(Data)是指对客观事物进行描述并可以鉴别的符号,这 些符号是可识别的、抽象的。它不仅指狭义上的数字,而是有多 种表现形式:字母、文字、文本、图形、音频、视频等。 
2 数据库
数据库是数据管理的有效技术,是由一批数据构成的有序集合, 这些数据被存放在结构化的数据表里。数据表之间相互关联,反 映客观事物间的本质联系。
3 数据库管理系统
数据库管理系统(Database Management System,DBMS) 是用来定义和管理数据的软件。
4 数据库应用程序
数据库应用程序(Database Application System,DBAS)是在 数据库管理系统基础上,使用数据库管理系统的语法,开发的直 接面对最终用户的应用程序。
5 数据库管理员
数据库管理员(Database Administrator,DBA)是指对数据库 管理系统进行操作的人员,其主要负责数据库的运营和维护。

数据库分类

image-20220110135345575

关系型数据库
关系型数据库最典型的数据结构是表,由二维表及其之间的联系所
组成的一个数据组
织。可以采用结构化查询语言(SQL)对数据库进行操作。
优点:
1 易于维护:都是使用表结构,格式一致;
2 使用方便:SQL语言通用,可用于复杂查询;
3 复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
缺点:
1 读写性能比较差,尤其是海量数据的高效率读写;
2 固定的表结构,灵活度稍欠;
3 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
非关系型数据库
非关系型数据库也称之为NoSQL数据库,是一种数据结构化存储方
法的集合,可以是文档或者键值对等。
优点:
1 格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形
式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
2 速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
3 高扩展性;
4 成本低:nosql数据库部署简单,基本都是开源软件。
缺点:
1 不提供sql支持,学习和使用成本较高;
2 无事务处理;
3 数据结构相对复杂,复杂查询方面稍欠。

MySQL基础知识

MySQL简介

MySQL 是一个关系型数据库管理系统, 由瑞典 MySQL AB 公司开 发, 目前属于 Oracle 公司。MySQL 是一种关系型数据库管理系 统,关系型数据库将数据保存在不同的表 中,而不是将所有数据放 在一个大仓库内,这样就增加了速度并提高了灵活性。

MySQL特点:

1、MySQL 是开源的。

2、MySQL 支持大型系统的数据库。可以处理拥有上千万条记录的大型 数据库。 MySQL 使用标准的 SQL 数据语言形式。

3、MySQL 可以运行于多个系统上,并且支持多种语言。这些编程语言 包括 C 、C++、 Python 、Java 、Perl 、PHP 等。

4、MySQL 存储数据量较大,32 位系统表文件最大可支持 4GB ,64 位系统支持最大的 表文件为 8TB。

5、MySQL 是可以定制的,采用了 GPL 协议,你可以修改源码来开发 自己的 MySQL 系 统。

MySQL分类

1、MySQL分为社区版

社区版是完全开源免费的,社区版也支持多种数据类型和标准的 SQL查询语言,能够对数据进行各种查询、增加、删除、修改等 操作,所以一般情况下社区版就可以满足开发需求了。

2、企业版

企业版是收费的。即使在开发中需要用到一些付费的附加功能, 价格相对于昂贵的 Oracle、DB2等也是有很大优势的。对数 据库可靠性要求比较高的企业可以选择企业版。

SQL语言

image-20220110140638641

SQL语言简介

结构化查询语言(Structured Query Language)简称 SQL(发音: sequal['si:kwəl]),是一种数据库查询和程序设计语言,用于存取数 据以及查询、更新和管理关系数据库系统。

SQL 能做什么?
SQL 面向数据库执行查询
SQL 可在数据库中插入新的记录
SQL 可更新数据库中的数据
SQL 可从数据库删除记录
SQL 可创建新数据库
SQL 可在数据库中创建新表
SQL 可在数据库中创建存储过程
SQL 可在数据库中创建视图
SQL 可以设置表、存储过程和视图的权限
SQL 标准

SQL 是 1986 年 10 月由美国国家标准局(ANSI)通过的数据库语 言美国标准,接着,国际标准化组织(ISO)颁布了 SQL 正式国际 标准。1989 年 4 月,ISO 提出了具有完整性特征的 SQL89 标准, 1992 年 11 月又公布了 SQL92 标准,在此标准中,把数据库分为三个级别:基本集、标准集和完全集。在 1999 年推出 99 版标准。 最新版本为 SQL2016 版。比较有代表性的几个版本:SQL86、 SQL92、SQL99。

SQL语言分类

1、数据查询语言(DQL:Data Query Language)其语句,也称为 “数据检索语句”,用以从表中获得数据,确定数据怎样在应用程 序给出。关键字 SELECT 是 DQL(也是所有 SQL)用得最多的 动词。

SELECT
FROM
WHERE
ORDER BY
HAVING

2、 数据操作语言(DML:Data Manipulation Language)其语句 包括动词 INSERT,UPDATE 和 DELETE。它们分别用于添加, 修改和删除表中的行。

INSERT:添加数据
UPDATE:更新数据
DELETE:删除数据

3、 数据定义语言(DDL:Data Definition Language)定义数据库 对象语言,其语句包括动词 CREATE 和 DROP 等。

CREATE:创建数据库对象
ALTER:修改数据库对象
DROP:删除数据库对象

4、数据控制语言(DCL:Data Control Language)它的语句通过 GRANT 或 REVOKE 获得许可,确定用户对数据库对象的访问。

GRANT:授予用户某种权限
REVOKE:回收授予的某种权限

5、事务控制语言(TCL :Transaction Control Language)它的语 句能确保被 DML 语句影响的表的所有行及时得以更新。

COMMIT:提交事务
ROLLBACK:回滚事务
SAVEPOINT:设置回滚点

注意: 数据操纵语言DML(insert、update、delete)针对表中的数 据 ; 而数据定义语言DDL(create、alter、drop)针对数据库对 象,比如数据库database、表table、索引index、视图view、 存储过程procedure、触发器trigger;

SQL语言语法

1、SQL语句不区分大小写,关键字建议大写。

2、 SQL语句可以单行或多行书写,以分号结尾。

创建与删除数据库

创建数据库

使用DDL语句创建数据库

CREATE DATABASE 数据库名 DEFAULT CHARACTER
SET 字符编码;

示例: 创建一个test 的数据库,并查看该数据库,以及该数据库的编 码。

创建数据库:

create database test default character set
utf8;

查看数据库:

 show databases;

查看数据库编码:

select
schema_name,default_character_set_name
from information_schema.schemata
where schema_name = 'test';
删除数据库

使用DDL语言删除数据库

 DROP DATABASE 数据库名称;

示例: 删除 test 数据库

drop database test;
选择数据库

在创建表时,需要先选择数据库。

USE 数据库名;

示例: 创建一个名称为 bjsxt 的数据库,编码为 utf8。

create database bjsxt default character set
utf8;

选择该数据库。

USE bjsxt;

MySQL数据库数据类型分类

image-20220110150557064

整数类型

image-20220110150717589

数值类型中的长度 m 是指显示长度,并不表示存储长度,只有字段 指定 zerofill 时有用

例如: int(3) ,如果实际值是 2 ,如果列指定了 zerofill ,查询结 果就是 002 ,左边用 0 来 填充

浮点类型

image-20220110150754984

字符类型

image-20220110150824151

char和varchar:
1 char长度固定, 即每条数据占用等长字节空间;适合用在身份证号码、手机号码等定长。
2 varchar可变长度,可以设置最大长度;适合用在长度可变的属性。
3 text不设置长度, 当不知道属性的最大长度时,适合用text。
按照查询速度: char最快, varchar次之,text最慢。

字符串型使用建议:
1 经常变化的字段用varchar
2 知道固定长度的用char
3 尽量用varchar
4 超过255字符的只能用varchar或者text
5 能用varchar的地方不用text
日期类型

image-20220110150930321

二进制数据(BLOB)
1、BLOB和TEXT存储方式不同,TEXT以文本方式存储,英文存储区分大小写,而Blob是以二进制方式
存储,不分大小写。
2、BLOB存储的数据只能整体读出。
3、TEXT可以指定字符集,BLOB不用指定字符集。

创建表与删除表

创建表

使用DDL语句创建表

CREATE TABLE 表名(列名 类型,列名 类型......);

示例: 创建一个 employees 表包含雇员 ID ,雇员名字,雇员薪水。

create table employees(employee_id
int,employee_name varchar(10),salary
float(8,2));

查看已创建的表。

 show tables;
删除表

使用DDL语句删除表

 DROP TABLE 表名;

示例: 删除 employees 表。

drop table employees;

修改表

修改表名

使用DDL语句修改表

 ALTER TABLE 旧表名 RENAME 新表名;

示例一: 创建一个 employees 表包含雇员 ID ,雇员名字,雇员薪水。

create table employees(employee_id
int,employee_name varchar(10),salary
float(8,2));

示例二: 将 employees 表名修改为 emp。

alter table employees rename emp;
修改列名

使用DDL语句修改列名

ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列
名 类型;

示例: 将 emp 表中的 employee_name 修改为 name。

alter table emp change column
employee_name name varchar(20);
修改列类型

使用DDL语句修改列类型

ALTER TABLE 表名 MODIFY 列名 新类型;

示例: 将 emp 表中的 name 的长度指定为 40。

alter table emp modify name varchar(40);
添加新列

使用DDL语句添加新列

ALTER TABLE 表名 ADD COLUMN 新列名 类型;

示例: 在 emp 表中添加佣金列,列名为 commission_pct。

alter table emp add column commission_pct
float(4,2);
删除指定列

使用DDL语句删除指定的列

ALTER TABLE 表名 DROP COLUMN 列名;

示例: 删除 emp 表中的 commission_pct。

alter table emp drop column
commission_pct;

MySQL中的约束

image-20220110151948093

约束概述

数据库约束是对表中的数据进行进一步的限制,保证数据的正确 性、有效性和完整性。

1、主键约束(Primary Key) PK

  • 主键约束是使用最频繁的约束。在设计数据表时,一般情况 下,都会要求表中设置一个主键。 主键是表的一个特殊字段,该字段能唯一标识该表中的每条 信息。例如,学生信息表中的学号是唯一的。

2、外键约束(Foreign Key) FK

  • 外键约束经常和主键约束一起使用,用来确保数据的一致 性。

3、唯一性约束(Unique)

  • 唯一约束与主键约束有一个相似的地方,就是它们都能够确 保列的唯一性。与主键约束不同的是,唯一约束在一个表中 可以有多个,并且设置唯一约束的列是允许有空值的。

4、非空约束(Not Null)

  • 非空约束用来约束表中的字段不能为空。

5、检查约束(Check)

  • 检查约束也叫用户自定义约束,是用来检查数据表中,字段 值是否有效的一个手段,但目前 MySQL 数据库不支持检查 约束。
添加主键约束(Primary Key)

1、单一主键

  • 使用一个列作为主键列,当该列的值有重复时,则违反唯一约 束。

2、联合主键

  • 使用多个列作为主键列,当多个列的值都相同时,则违反唯一约 束。
修改表添加主键约束

使用DDL语句添加主键约束

ALTER TABLE 表名 ADD PRIMARY KEY(列名)

示例: 将 emp 表中的 employee_id 修改为主键。

alter table emp add primary
key(employee_id);
主键自增长

MySQL 中的自动增长类型要求:

  • 一个表中只能有一个列为自动增长。
  • 自动增长的列的类型必须是整数类型。
  • 自动增长只能添加到具备主键约束与唯一性约束的列上。
  • 删除主键约束或唯一性约束,如果该列拥有自动增长能力,则需要先去掉自动增长然 后在删 除约束。
alter table 表名 modify 主键 类型
auto_increment;

示例: 将 emp 表中的 employee_id 主键修改为自增。

alter table emp modify employee_id int
auto_increment;
删除主键

使用DDL语句删除主键

ALTER TABLE 表名 DROP PRIMARY KEY;

注意: 删除主键时,如果主键列具备自动增长能力,需要先去掉自 动增长,然后在删除 主键。

示例: 删除emp表中的 employee_id 主键约束。 去掉自动增长:

 alter table emp modify employee_id int;

删除主键:

alter table emp drop primary key;

添加外键约束(Foreign Key)

image-20220110153927989

修改表添加外键约束

使用DDL语句添加外键约束

ALTER  TABLE 表名 ADD CONSTRAINT 约束名
FOREIGN  KEY( 列 名 ) REFERENCES 参照的表名
(参照的列名);

示例一: 创建 departments 表包含 department_id 、 department_name ,location_id。

create table departments(department_id
int,department_name
varchar(30),location_id int);

示例二: 修改departments表,向department_id列添加主键约束与自动 递增。

alter table departments add primary
key(department_id);
alter table departments modify
department_id int auto_increment;

示例三: 修改 emp 表,添加 dept_id 列。

alter table emp add column dept_id int;

示例四: 向 emp 表中的 dept_id 列添加外键约束。

alter table emp add constraint emp_fk
foreign key(dept_id) references
departments(department_id);
删除外键约束

使用DDL语句删除外键约束。

ALTER TABLE 表名 DROP FOREIGN KEY 约束名;

示例: 删除 dept_id 的外键约束。

alter table emp drop foreign key emp_fk;

添加唯一性约束(Unique)

修改表添加唯一性约束

使用DDL语句添加唯一性约束。

ALTER TABLE 表名 ADD CONSTRAINT 约束名
UNIQUE(列名);

示例: 向 emp 表中的 name 添加唯一约束。

alter table emp add constraint emp_uk
unique(name);
删除唯一性约束

使用DDL语句删除唯一性约束。

ALTER TABLE 表名 DROP KEY 约束名;

示例: 删除 name 的唯一约束。

alter table emp drop key emp_uk;

非空约束(Not Null)

修改表添加非空约束

使用DDL语句添加非空约束。

ALTER TABLE 表名 MODIFY 列名 类型 NOT
NULL;

示例: 向 emp 表中的 salary 添加非空约束。

alter table emp modify salary float(8,2)
not NULL;
删除非空约束

使用DDL语句删除非空约束。

ALTER TABLE 表名 MODIFY 列名 类型 NULL;

示例: 删除emp表中salary 的非空约束。

alter table emp modify salary float(8,2)
NULL;
创建表时添加约束

查询表中的约束信息:

SHOW KEYS FROM 表名;

示例: 创建 depts 表包含 department_id 该列为主键且自动增长, department_name 列不 允许重复,location_id 列不允含有空值。

create table depts(department_id int primary
key auto_increment,department_name
varchar(30) unique,location_id int not null);

MySQL中DML操作

image-20220110154751891

添加数据(INSERT)

选择插入

INSERT INTO 表名(列名 1 ,列名 2 ,列名
3.....) VALUES(值 1 ,值 2 ,值 3......);

示例: 向 departments 表中添加一条数据,部门名称为 market ,工 作地点 ID 为 1。

insert into
departments(department_name,location_id)
values("market", 1);

完全插入

INSERT INTO 表名 VALUES(值 1 ,值 2 ,值
3......);

注意: 如果主键是自动增长,需要使用 default 或者 null 或者 0 占 位。

示例一: 向 departments 表中添加一条数据,部门名称为 development , 工作地点 ID 为 2 。使用 default 占位。

insert into departments
values(default,"development",2);

示例二: 向 departments 表中添加一条数据,部门名称为human ,工作地 点 ID 为 3 。使用 null 占 位。

insert into departments
values(null,"human",3);

示例三: 向 departments 表中添加一条数据,部门名称为 teaching ,工作 地点 ID 为 4 。使用 0 占 位。

insert into departments
values(0,"teaching",4);
默认值处理(DEFAULT)

在 MySQL 中可以使用 DEFAULT 为列设定一个默认值。如果在插入 数据时并未指定该列的值,那么 MySQL 会将默认值添加到该列 中。

创建表时指定列的默认值
CREATE TABLE 表名(列名 类型 default 默认
值,......);

示例: 创建 emp3 表,该表包含 emp_id 主键且自动增长,包含 name , 包含 address 该列默认 值为”未知”。

create table emp3(emp_id int primary key
auto_increment,name varchar(10),address
varchar(50) default 'Unknown');
修改表添加新列并指定默认值
ALTER TABLE 表名 ADD COLUMN 列名 类型 DEFAULT
默认值;

示例: 修改 emp3 表,添加job_id 该列默认值为 0。

alter table emp3 add column job_id int
default 0;

插入数据时的默认值处理

如果在插入数据时并未指定该列的值,那么MySQL 会将默认值添加 到该列中。如果是 完全项插入需要使用 default 来占位。

示例: 向 emp3 表中添加数据,要求 address 列与job_id 列使用默认值作 为该列的值。

insert into emp3(name) values("admin");
insert into emp3
values(default,"oldlu",default,default);
更新数据(UPDATE)
 UPDATE 表名 SET 列名=值,列名=值 WHERE 条件;
  • 注意: 更新语句中一定要给定更新条件,否则表中的所有数据都会被 更新。

示例: 更新 emp3 表中的 id 为 1 的数据,添加 address 为 BeiJing。

update emp3 set address = "BeiJing" where
emp_id = 1;

删除数据(DELETE)

DELETE删除数据
DELETE FROM 表名 WHERE 条件

注意: 在DELETE语句中,如果没有给定删除条件则会删除表中的所有 数据。

示例: 删除 emp3 表中 emp_id 为 1 的雇员信息。

delete from emp3 where emp_id = 1;
TRUNCATE清空表
TRUNCATE TABLE 表名;

示例: 删除 emp3 表中的所有数据。

truncate table emp3;
清空表时DELETE与 TRUNCATE 区别
truncate 是整体删除(速度较快), delete 是逐条删除(速度较慢);
truncate 不写服务器 log,delete 写服务器 log,也就是 truncate 效率比 delete 高的原因;
truncate 是会重置自增值,相当于自增列会被置为初始值,又重新从 1 开始记录,而 不是接着原
来的值。而 delete 删除以后, 自增值仍然会继续累加。

MySQL查询数据

SELECT基本查询

SELECT语句的功能

SELECT 语句从数据库中返回信息。使用一个 SELECT 语句,可以做 下面的事:

  • 列选择:能够使用 SELECT 语句的列选择功能选择表中的列,这 些列是想 要用查询返回的。当查询时,能够返回列中的数据。
  • 行选择:能够使用 SELECT 语句的行选择功能选择表中的行,这 些行是想 要用查询返回的。能够使用不同的标准限制看见的行。
  • 连接:能够使用 SELECT 语句的连接功能来集合数据,这些数据 被存储在不 同的表中,在它们之间可以创建连接,查询出我们所关心的数 据。
SELECT基本语法

image-20220110155728648

基本 SELECT 语句

在最简单的形式中,SELECT 语句必须包含下面的内容:

  • 一个 SELECT 子句,指定被显示的列

  • 一个 FROM 子句,指定表,该表包含 SELECT 子句中的字段列 表

在语法中:

image-20220110155812112

查询中的列选择

选择所有列

image-20220110155908396

用跟在 SELECT 关键字后面的星号 (*),你能够显示表中数据的所有 列。

示例: 查询 departments 表中的所有数据。

select * from departments;
选择指定列

image-20220110155951545

能够用 SELECT 语句来显示表的指定列,指定列名之间用逗号分 隔。

示例: 查询 departments 表中所有部门名称。

select department_name from departments;
查询中的算术表达式

image-20220110160037902

需要修改数据显示方式,如执行计算,或者作假定推测,这些都可 能用到算 术表达式。一个算术表达式可以包含列名、固定的数字值和算术运 算符。

image-20220110160054132

示例: 查询雇员的年薪,并显示他们的雇员ID,名字。

select employees_id,last_name, 12*salary from
employees;

image-20220110160115986

如果算术表达式包含有一个以上的运算,乘法和除法先计算。如果 在一个表达式中的运算符优先级相同,计算从左到右进行。可以用圆括号强制其中 的表达式先计算。

示例一: 计算 employees 表中的员工全年薪水加 100 以后的薪水是多少, 并显示他们的员工ID与名字。

select employees_id,last_name, 12*salary+100
from employees;

示例二: 计算 employees 表中的员工薪水加 100 以后的全年薪水是多少, 并显示他们的员工ID与名字。

select employees_id,last_name, 12*
(salary+100) from employees;
MySQL中定义空值

image-20220110160215033

如果一行中的某个列缺少数据值,该值被置为 null, 或者说包含一 个空。 空是一个难以获得的、未分配的、未知的,或不适用的值。空和 0 或者空格不相同。 0 是一个数字,而空格是一个字符。

算术表达式中的空值

image-20220110160238017

示例: 计算年薪包含佣金。

select 12*salary*commission_pct from
employees;
MySQL中的别名

使用列别名

image-20220110160317090

SELECT 列名 AS 列别名 FROM 表名 WHERE 条件;

示例: 查询 employees 表将雇员 last_name 列定义别名为 name。

select last_name as name from employees;
select last_name name from employees;
使用表别名
SELECT 表别名.列名  FROM 表名 as 表别名 WHERE 
条件;

示例: 查询 employees 表为表定义别名为emp,将雇员 last_name 列定 义别名为 name。

select emp.last_name name from employees emp;
MySQL中去除重复

image-20220110160441362

image-20220110160453931

 SELECT DISTINCT 列名 FROM 表名;

示例: 查询 employees 表,显示唯一的部门 ID。

select distinct department_id from employees;
查询中的行选择

image-20220110160630047

用 WHERE 子句限制从查询返回的行。一个 WHERE 子句包含一个 必须满足的条件,WHERE 子句紧跟着 FROM 子句。如果条件是 true,返回满足条件的行。

在语法中:

WHERE 限制查询满足条件的行

condition 由列名、表达式、常数和比较操作组成

SELECT * | 投影列 FROM 表名 WHERE 选择条件;

示例: 查询 departments 表中部门 ID 为 90 的部门名称与工作地点 ID。

select department_name,location_id from
departments where department_id =4;
MySQL中的比较条件

image-20220110160755875

符号 != 也能够表示 不等于条件。

示例一: 查询 employees 表中员工薪水大于等于 3000 的员工的姓名与薪 水。

select last_name,salary from employees where
salary >= 3000;

示例二: 查询 employees 表中员工薪水不等于 5000 的员工的姓名与薪水。

select last_name,salary from employees where
salary<>5000;
其他比较条件

image-20220110160851828

使用BETWEEN条件

image-20220110160910520

可以用 BETWEEN 范围条件显示基于一个值范围的行。指定的范围 包含一个下限和一个上限。

示例: 查询 employees 表,薪水在 3000-8000 之间的雇员ID、名字与薪 水。

select employee_id,last_name,salary from
employees where salary between 3000 and 8000;
使用IN条件

image-20220110160953477

示例: 查询 employees 表,找出薪水是 5000,6000,8000 的雇员ID、名字 与薪水。

select employee_id,last_name,salary from
employees where salary in(5000,6000,8000);
使用LIKE条件

image-20220110161030174

示例: 查询 employees 中雇员名字第二个字母是 e 的雇员名字。

select last_name from employees where
last_name like '_e%';

image-20220110161108509

NULL 条件,包括 IS NULL 条件和 IS NOT NULL 条件。IS NULL 条件用于空值测试。空值的意思是难以获得的、未指定 的、未知的或者不适用的。因此,你不能用 = ,因为 null 不能等于 或不等于任何值。

示例一: 找出 emloyees 表中那些没有佣金的雇员雇员ID、名字与佣金。

select employee_id,last_name,commission_pct
from employees where commission_pct is null;

示例二: 找出 employees 表中那些有佣金的雇员ID、名字与佣金。

select employee_id,last_name,commission_pct
from employees where commission_pct is not
null;
逻辑条件

image-20220110161246212

逻辑条件组合两个比较条件的结果来产生一个基于这些条件的单个 的结果,或者逆

转一个单个条件的结果。当所有条件的结果为真时,返回行。 SQL 的三个逻辑运算符是:

AND
OR
NOT

可以在 WHERE 子句中用 AND 和 OR 运算符使用多个条件。

示例一: 查询 employees 表中雇员薪水是 8000 的并且名字中含有e 的雇员 名字与薪水。

select last_name,salary from employees where
salary = 8000 and last_name like '%e%';

示例二: 查询 employees 表中雇员薪水是 8000 的或者名字中含有e 的雇员 名字与薪水。

select last_name,salary from employees where
salary = 8000 or last_name like '%e%';

示例三: 查询 employees 表中雇员名字中不包含 u 的雇员的名字。

select last_name from employees where
last_name not like '%u%';
优先规则

image-20220110162807180

image-20220110162820562

在图片的例子中,有两个条件:

第一个条件是 job_id 是 AD_PRES 并且薪水高于 15,000。
第二个条件是 job_id 是 SA_REP。

image-20220110162909768

在图片中的例子有两个条件:

第一个条件是 job_id 是 AD_PRES 或者 SA_REP 。
第二个条件是薪水高于$15,000
使用 ORDER BY 排序

image-20220110162943153

在一个不明确的查询结果中排序返回的行。ORDER BY 子句用于排 序。如果使用了 ORDER BY 子句,它必须位于 SQL 语句的最后。

SELECT 语句的执行顺序如下:

FROM 子句
WHERE 子句
SELECT 子句
ORDER BY 子句

示例一: 查询 employees 表中的所有雇员,显示他们的ID、名字与薪水,并 按薪水升序排序。

select employee_id,last_name,salary from
employees order by salary;
select employee_id,last_name,salary from
employees order by salary asc;

示例二: 查询 employees 表中的所有雇员,显示他们的ID与名字,并按雇员 名字降序排序。

select employee_id,last_name from employees
order by last_name desc;

使用别名排序

image-20220110163117785

示例:

显示雇员ID,名字。计算雇员的年薪,年薪列别名为annsal,并对 该列进行升序排序,

select employee_id,last_name ,12*salary
annsal from employees order by annsal;
多列排序

image-20220110163200731

示例: 以升叙排序显示 DEPARTMENT_ID 列,同时以降序排序显示 SALARY 列。

select department_id,salary from employees
order by department_id asc ,salary desc;

练习

1.创建一个查询,显示收入超过 12,000 的雇员的名字和薪水。

select
LAST_NAME,SALARY
from employees
WHERE SALARY > 12000;

2.创建一个查询,显示雇员号为 176 的雇员的名字和部门号。

SELECT
LAST_NAME,DEPARTMENT_ID
from employees
where EMPLOYEE_ID = 176;

3.显示所有薪水不在 5000 和 12000 之间的雇员的名字和薪水。

select
LAST_NAME,SALARY
from employees
where salary not BETWEEN 5000 and 12000;

4.显示所有在部门 20 和 50 中的雇员的名字和部门号,并以名字按 字母顺序排序。

LAST_NAME,DEPARTMENT_ID
FROM employees
WHERE DEPARTMENT_ID IN (20,50)
ORDER BY LAST_NAME asc;

5.列出收入在 5,000 和 12,000 之间,并且在部门 20 或50 工作的雇 员的名字和薪水。将列标题分别显示为 Employee 和 Monthly Salary

SELECT
LAST_NAME Employee,SALARY 'Monthly Salary'
FROM employees
WHERE SALARY BETWEEN 5000 and 12000
AND
DEPARTMENT_ID in(20,50);

6.显示所有没有主管经理的雇员的名字和工作岗位。

SELECT
LAST_NAME,JOB_ID
FROM employees
WHERE MANAGER_ID is null;

7.显示所有有佣金的雇员的名字、薪水和佣金。以薪水和佣金的降 序排序数据。

SELECT
LAST_NAME,SALARY,COMMISSION_PCT
from employees
where COMMISSION_PCT is not NULL
ORDER BY SALARY DESC , COMMISSION_PCT desc;

8.显示所有名字中有一个 a 和一个 e 的雇员的名字。

SELECT
LAST_NAME
from employees
where LAST_NAME LIKE '%a%'
AND
LAST_NAME LIKE '%e%';

9.显示所有工作岗位是销售代表(SA_REP)或者普通职员 (ST_CLERK),并且薪水不等于 2,500、3,500 或 7,000 的雇员的名 字、工作岗位和薪水。

SELECT
LAST_NAME,JOB_ID,SALARY
from employees
WHERE
JOB_ID in('SA_REP','ST_CLIERK')
AND
SALARY not IN(2500,3500,7000)

SQL函数

函数介绍

image-20220110163525385

函数是 SQL 的一个非常强有力的特性,函数能够用于下面的目的:

执行数据计算
修改单个数据项
操纵输出进行行分组
格式化显示的日期和数字
转换列数据类型

SQL 函数有输入参数,并且总有一个返回值。

函数分类

image-20220110163607547

单行函数 单行函数仅对单个行进行运算,并且每行返回一个结果。 常见的函数类型:

字符
数字
日期
转换

多行函数

多行函数能够操纵成组的行,每个行组给出一个结果,这些函数 也被称为组函数。

单行函数

image-20220110163752789

单行函数分类

image-20220110163816624

字符函数

image-20220110163840316

大小写处理函数

image-20220110163856763

示例: 显示雇员 Davies 的雇员号、姓名和部门号,将姓名转换为大写。

select
employee_id,UPPER(last_name),department_id
from employees where last_name = 'davies';

字符处理函数

image-20220110164001266

示例: 显示所有工作岗位名称从第 4 个字符位置开始,包含字符串 REP的 雇员的ID信息,将雇员的姓和名连接显示在一起,还显示雇员名的 的长度,以及名字中字母 a 的位置。

SELECT employee_id, CONCAT(last_name,
first_name) NAME,
job_id, LENGTH(last_name),INSTR(last_name,
'a') "Contains 'a'?" FROM employees WHERE
SUBSTR(job_id, 4) = 'REP';
数字函数

image-20220110164120289

image-20220110164140123

image-20220110164153946

ROUND(column|expression, n) 函数

ROUND 函数四舍五入列、表达式或者 n 位小数的值。如果第二个 参数是 0 或者缺少,值被四舍五入为整数。如果第二个参数是 2值 被四舍五入为两位小数。如果第二个参数是–2,值被四舍五入到小 数点左边两位。

SELECT ROUND(45.923,2),
ROUND(45.923,0),ROUND(45.923,-1);
TRUNCATE(column|expression,n) 函数

TRUNCATE函数的作用类似于 ROUND 函数。如果第二个参数是 0 或者缺少,值被截断为整数。如果第二个参数是 2,值被截断为两 位小数。如果第二个参数是–2,值被截断到小数点左边两位。与 ROUND 最大的区别是不会进行四舍五入。

SELECT TRUNCATE(45.923,2);
使用MOD(m,n) 函数

MOD 函数找出m 除以n的余数。 示例: 所有job_id是SA_REP的雇员的名字,薪水以及薪水被5000除后的余 数。

SELECT last_name, salary, MOD(salary, 5000)
FROM employees
WHERE job_id = 'SA_REP';
日期函数

在MySQL中允许直接使用字符串表示日期,但是要求字符串的日期 格式必须为:‘YYYY-MM-DD HH:MI:SS’ 或者‘YYYY/MM/DD HH:MI:SS’;

image-20220110164358630

image-20220110164415566

示例一:

向 employees 表中添加一条数据,雇员ID:300,名字:kevin , email:kevin@sxt.cn ,入职时间:2049-5-1 8:30:30,工作部 门:‘IT_PROG’。

insert  into
employees(EMPLOYEE_ID,last_name,email,HIRE_DA
TE,JOB_ID)
values(300,'kevin','kevin@sxt.cn','2049-5-1
8:30:30','IT_PROG');

示例二: 显示所有在部门 90 中的雇员的名字和从业的周数。雇员的总工作 时间以周计算,用当前日期 (SYSDATE) 减去雇员的受顾日期,再除 以 7。

SELECT last_name, (SYSDATE()-hire_date)/7 AS
WEEKS FROM employees WHERE department_id =
90;
转换函数

image-20220110164547672

隐式数据类型转换

隐式数据类型转换是指MySQL服务器能够自动地进行类型转换。 如:可以将标准格式的字串日期自动转换为日期类型。

MySQL字符串日期格式为:‘YYYY-MM-DD HH:MI:SS’ 或 ‘YYYY/MM/DD HH:MI:SS’;

显示数据类型转换

显示数据类型转换是指需要依赖转换函数来完成相关类型的转换。 如:

DATE_FORMAT(date,format) 将日期转换成字符串;
STR_TO_DATE(str,format) 将字符串转换成日期;

image-20220110165057575

示例一: 向 employees 表中添加一条数据,雇员ID:400,名字:oldlu , email:oldlu@sxt.cn ,入职时间:2049 年 5 月 5 日,工作部 门:‘IT_PROG’。

insert  into
employees(EMPLOYEE_ID,last_name,email,HIRE_DA
TE,JOB_ID)
values(400,'oldlu','oldlu@sxt.cn',
STR_TO_DATE('2049 年 5 月 5 日'
,'%Y 年%m 月%d
日'),'IT_PROG');

示例二: 查询 employees 表中雇员名字为 King 的雇员的入职日期,要求显 示格式为 yyyy 年 MM 月 dd 日。

select DATE_FORMAT(hire_date,'%Y 年%m 月%d
日') from employees where last_name = 'King';
通用函数

image-20220110165145467

示例一: 查询部门编号是50或者80的员工信息,包含他们的名字、薪水、佣 金。在income列中,如果有佣金则显示‘SAL+COMM’,无佣金则显 示'SAL'。

SELECT last_name, salary, commission_pct,    
    if(ISNULL(commission_pct),
'SAL','SAL+COMM') income
FROM employees
WHERE department_id IN (50, 80);

示例二:计算雇员的年报酬,你需要用 12 乘以月薪,再加上它的佣金 (等于 年薪乘以佣金 百分比)。

SELECT last_name, salary,
IFNULL(commission_pct, 0), (salary*12) +
(salary*12*IFNULL(commission_pct, 0)) AN_SAL
FROM employees;

示例三 查询员工表,显示他们的名字、名字的长度该列名为expr1,姓 氏、姓氏的长度该列名为expr2。在result列中,如果名字与姓氏的 长度相同则显示空,如果不相同则显示名字长度。

SELECT first_name, LENGTH(first_name)
"expr1",
       last_name, LENGTH(last_name) "expr2",
    NULLIF(LENGTH(first_name),
LENGTH(last_name)) result
FROM employees;

示例四: 查询员工表,显示他们的名字,如果 COMMISSION_PCT 值是非 空,显示它。如果COMMISSION_PCT 值是空,则显示 SALARY 。 如果 COMMISSION_PCT 和SALARY 值都是空,那么显示 10。在结 果中对佣金列升序排序。

SELECT last_name,
COALESCE(commission_pct, salary, 10) comm
FROM employees
ORDER BY commission_pct;

示例五: 查询员工表,如果 JOB_ID 是 IT_PROG,薪水增加 10%;如果 JOB_ID 是 ST_CLERK,薪水增加 15%;如果 JOB_ID 是 SA_REP, 薪水增加 20%。对于所有其他的工作角色,不增加薪水。

SELECT last_name, job_id, salary,
        CASE job_id WHEN 'IT_PROG' THEN
1.10*salary
                    WHEN 'ST_CLERK' THEN
1.15*salary
                    WHEN 'SA_REP' THEN
1.20*salary
        ELSE salary END "REVISED_SALARY"
FROM employees;

练习

1.显示受雇日期在 1998 年 2 月 20 日 和 2005 年 5 月 1 日 之间的 雇员的名字、岗位 和受雇日期。按受雇日期顺序排序查询结果。

SELECT
LAST_NAME,JOB_ID,HIRE_DATE
FROM employees
WHERE HIRE_DATE BETWEEN '1998-2-20' AND
'2005-5-1'
order by HIRE_DATE;

2.显示每一个在 2002 年受雇的雇员的名字和受雇日期

select
LAST_NAME,HIRE_DATE
FROM employees
where HIRE_DATE like '2002%'

3.对每一个雇员,显示 employee number、last_name、salary 和 salary 增加 15%, 并且表示成整数,列标签显示为 New Salary。

SELECT
EMPLOYEE_ID,LAST_NAME,SALARY,
ROUND(SALARY *1.15,0)
FROM employees

4.写一个查询,显示名字的长度,对所有名字开始字母是 J、A 或 M 的雇员。用雇员的 last name排序结果。

SELECT
LAST_NAME,
LENGTH(LAST_NAME)
FROM employees
WHERE LAST_NAME LIKE 'J%'
OR
LAST_NAME LIKE 'A%'
OR
LAST_NAME LIKE 'M%'
ORDER BY LAST_NAME;

5.创建一个查询显示所有雇员的 last name 和 salary。将薪水格式 化为 15 个字符长度,用 $左填充 。

SELECT
LAST_NAME,LPAD(SALARY,15,'$')
FROM employees;

6.创建一个查询显示雇员的 last names 和 commission (佣金) 比 率。如果雇员没有佣金,显示 “No Commission”,列标签 COMM。

SELECT
LAST_NAME,IFNULL(COMMISSION_PCT,'No
Commission') COMM
FROM employees

7.写一个查询,按照下面的数据显示所有雇员的基于 JOB_ID 列值的 级别。

SELECT JOB_ID,
   CASE JOB_ID WHEN 'AD_PRES' THEN 'A'
               WHEN 'ST_MAN' THEN 'B'
           WHEN 'IT_PROG' THEN 'C'
           WHEN 'SA_REP' THEN 'D'
               WHEN 'ST_CLERK' THEN 'E'
   ELSE 0 END
FROM employees;

多表查询

多表查询简介

image-20220110165533635

笛卡尔乘积

image-20220110165548025

笛卡尔乘积 : 当一个连接条件无效或被遗漏时,其结果是一个笛卡尔乘积 (Cartesian product),其中所有行的组合都被显示。第一个表中的所 有行连接到第二个表中的所有行。一个笛卡尔乘积会产生大量的 行,其结果没有什么用。你应该在 WHERE 子句中始终包含一个有 效的连接条件,除非你有特殊的需求,需要从所有表中组合所有的 行。

image-20220110165608555

多表查询分类

sql92标准:内连接(等值连接 、非等值连接 、 自连接)。
sql99标准:内连接、外连接(左外、右外、全外(MySQL不支持全外连接))、交叉连接。
SQL92标准中的查询

等值连接

image-20220110165659058

等值连接

为了确定一个雇员的部门名,需要比较 EMPLOYEES 表中的 DEPARTMENT_ID 列与DEPARTMENTS 表中的 DEPARTMENT_ID 列的值。在 EMPLOYEES 和DEPARTMENTS 表之间的关系是一个相 等 (equijoin) 关系,即,两 个 表 中DEPARTMENT_ID 列的值必须相 等。

等值连接特点:

1 多表等值连接的结果为多表的交集部分;
2 n表连接,至少需要n-1个连接条件;
3 多表不分主次,没有顺序要求;
4 一般为表起别名,提高阅读性和性能;
5 可以搭配排序、分组、筛选….等子句使用;

注意: 等值连接也被称为简单连接 (simple joins) 或内连接 (inner joins)。

等值连接的使用

image-20220110165753452

SELECT 子句指定要返回的列名: − employee last name、employee number 和 department number,这些是 EMPLOYEES 表中的列 − department number、department name 和 location ID, 这些是 DEPARTMENTS 表中的列

FROM 子句指定数据库必须访问的两个表: − EMPLOYEES 表

− DEPARTMENTS 表

WHERE 子句指定表怎样被连接: EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID,因为 DEPARTMENT_ID 列 是两个表的同名列,它必须用表名做前缀以避免混淆。

增加搜索条件

image-20220110165858810

添加查询条件

除连接之外,可能还要求用 WHERE 子句在连接中限制一个或多个 表中的行。

限制不能缺的列

image-20220110165936604

限制不明确的列名
需要在 WHERE 子句中用表的名字限制列的名字以避免含糊不清。没有表前缀,DEPARTMENT_ID
列可能来自 DEPARTMENTS 表,也可能来自 EMPLOYEES 表,这种情况下需要添加表前缀来执行
查询。
如果列名在两个表之间不相同,就不需要限定列。但是,使用表前缀可以改善性能,因为MySQL服
务器可以根据表前缀找到对应的列。
必须限定不明确的列名也适用于在其它子句中可能引起混淆的那些列,例如 SELECT子句或 ORDER
BY 子句。
使用表别名

image-20220110170014635

表别名定义原则
表别名不易过长,短一些更好。
表别名应该是有意义的。
表别名只对当前的 SELECT 语句有效。
多表连接

image-20220110170048454

示例一: 查询雇员 King 所在的部门名称。

select d.department_name from employees
e,departments d   where e.dept_id =
d.department_id and e.last_name = 'King';

示例二: 显示每个雇员的 last name、departmentname 和 city。

SELECT e.last_name, d.department_name, l.city
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id;
非等值连接

image-20220110170137581

非等值连接

一个非等值连接是一种不同于等值操作的连接条件。 EMPLOYEES 表 和JOB_GRADES A 表之间的关系有一个非等值连接例子。在两个 表之间的关系是EMPLOYEES 表中的 SALARY 列必须是 JOB_GRADES 表的 LOWEST_SALARY 和HIGHEST_SALARY 列之间 的值。使用不同于等于 (=) 的操作符获得关系。

image-20220110170243039

示例一: 创建 job_grades 表,包含 lowest_sal ,highest_sal , grade_level。

create table job_grades(lowest_sal
int,highest_sal int ,grade_level
varchar(30));

示例二: 插入数据

1000 2999 A

2000 4999 B

5000 7999 C

8000 12000 D

insert into job_grades values(1000,2999,'A');
insert into job_grades values(2000,4999,'B');
insert into job_grades values(5000,7999,'C');
insert into job_grades
values(8000,12000,'D');

示例三: 查询所有雇员的薪水级别。

select e.last_name,j.grade_level from
employees e ,job_grades j where e.salary
between j.lowest_sal and j.highest_sal;
自连接

image-20220110170427053

自连接

连接一个表到它自己。有时需要连接一个表到它自己。为了找到每 个雇员的经理的名字,则需要连接EMPLOYEES 表到它自己,或执 行一个自连接。

image-20220110170448914

图片中的例子连接 EMPLOYEES 表到它自己。为了在 FROM 子句中 模拟两个表,对于相同的表 EMPLOYEES,用两个别名,分别为 worker 和 manager。在该例中,WHERE 子句包含的连接意味着 “一个工人的经理号匹配该经理的雇员号”。

示例一:

查询每个雇员的经理的名字以及雇员的名字,雇员名字列别名为 W,经理列别名为M。

SELECT
worker.LAST_NAME W,manager.LAST_NAME M
from employees worker,employees manager
where worker.MANAGER_ID =
manager.EMPLOYEE_ID;

示例二: 查询Fox的经理是谁?显示他的名字。

SELECT
worker.LAST_NAME,manager.LAST_NAME
from employees worker,employees manager
where worker.MANAGER_ID = manager.EMPLOYEE_ID
AND
worker.LAST_NAME = 'Fox';
SQL99标准中的查询

MySQL5.7 支持部分的SQL99 标准。 SQL99中的交叉连接(CROSS JOIN)

image-20220110171056277

示例: 使用交叉连接查询 employees 表与 departments 表。

select * from employees cross join
departments;
SQL99中的自然连接(NATURAL JOIN)

image-20220110171128612

自然连接

连接只能发生在两个表中有相同名字和数据类型的列上。如果列有 相同的名字,但 数据类型不同,NATURAL JOIN 语法会引起错误。

自然连接查询

image-20220110171156175

在图片例子中,LOCATIONS 表被用 LOCATION_ID 列连接到 DEPARTMENT表,这是在两个表中唯一名字相同的列。如果存在其 它的同名同类型的列,自然连接会使用等值连接的方式连接他们, 连接条件的关系为and。

自然连接也可以被写为等值连接:

 SELECT d.department_id, d.department_name,
 d.location_id , l.city
FROM
 departments d , locations l
 WHERE
 d.location_id = l.location_id;

示例: 使用自然连接查询所有有部门的雇员的名字以及部门名称。

select e.last_name,d.department_name from
employees e natural join departments d;
SQL99中的内连接(INNER JOIN)

image-20220110171250802

语法:

SELECT 查询列表;
FROM 表1 别名;
INNER JOIN 连接表(INNER关键字可省略);
ON 连接条件;

用ON子句指定连接条件

image-20220110171330229

用ON子句指定更多的连接条件

image-20220110171346409

示例: 查询雇员名字为 Fox 的雇员 ID ,薪水与部门名称。

select
e.employee_id,e.salary,d.department_name from
employees e inner JOIN departments d on
e.department_id = d.department_id where
e.last_name = 'Fox';
外连接查询(OUTER JOIN)

image-20220110171420654

孤儿数据(Orphan Data)

孤儿数据是指被连接的列的值为空的数据。

左外连接(LEFT OUTER JOIN)

image-20220110171452318

image-20220110171502072

左外连接

左边的表 (EMPLOYEES) 中即使没有与 DEPARTMENTS 表中匹配的 行,该查询 也会取回 EMPLOYEES 表中所有的行。

示例: 查询所有雇员的名字以及他们的部门名称,包含那些没有部门的雇 员。

select e.last_name,d.department_name from
employees e LEFT OUTER JOIN departments d on
e.dept_id = d.department_id;
右外连接(RIGTH OUTER JOIN)

image-20220110171556972

image-20220110171606776

右外连接

右边的表 (DEPARTMENTS ) 中即使没有与 EMPLOYEES 表中匹配的 行,该查询 也会取回 DEPARTMENTS 表中所有的行。

示例: 查询所有雇员的名字以及他们的部门名称,包含那些没有雇员的部 门。

select e.last_name,d.department_name  from 
employees e RIGHT  OUTER JOIN departments 
d on e.DEPARTMENT_ID = d.department_id;
全外连接(FULL OUTER JOIN)

image-20220110171704418

可以使用 union 实现全完连接。

UNION: 可以将两个查询结果集合并,返回的行都是唯一的,如同对整个结果集合使用了
DISTINCT。
UNION ALL: 只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数
据, 那么返回的结果集就会包含重复的数据了。

语法结构

	(SELECT 投影列 FROM 表名 LEFT OUTER JOIN 表名
ON 连接条件)
UNION
(SELECT 投影列 FROM 表名 RIGHT OUTER JOIN 表
名 ON 连接条件)

示例: 查询所有雇员的名字以及他们的部门名称,包含那些没有雇员的部 门以及没有部门的雇 员。

(select e.last_name,d.department_name from
employees e LEFT OUTER JOIN departments d  on
e.department_id = d.department_id)  
UNION  
(select e1.last_name,d1.department_name
from employees e1 RIGHT OUTER JOIN
departments d1 on d1.department_id =
e1.department_id)

练习

1.写一个查询显示所有雇员的 last name、department id、and department name。

SELECT
e.LAST_NAME,e.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM employees e,departments d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID;

2.创建一个在部门 80 中的所有工作岗位的唯一列表,在输出中包括 部门的地点。

SELECT DISTINCT
e.JOB_ID,d.LOCATION_ID
FROM employees e,departments d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.DEPARTMENT_ID = 80;

3.写一个查询显示所有有佣金的雇员的 last name、department name、location ID 和城 市

SELECT
e.LAST_NAME,d.DEPARTMENT_NAME,d.LOCATION_ID,l
.CITY
FROM employees e,departments d,locations l
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND d.LOCATION_ID = l.LOCATION_ID
AND e.COMMISSION_PCT is not null;

4.显示所有在其 last names 中有一个小写 a 的雇员的 last name 和 department

select
e.LAST_NAME,d.DEPARTMENT_NAME
FROM employees e,departments d
where e.DEPARTMENT_ID = d.DEPARTMENT_ID
AND e.LAST_NAME like '%a%';

5.用sql99的内连接写一个查询显示那些工作在 Toronto 的所有雇员 的 last name、job、department number 和 department name。

SELECT
e.LAST_NAME,e.JOB_ID,e.DEPARTMENT_ID,d.DEPART
MENT_NAME
FROM employees e INNER JOIN departments d
ON e.DEPARTMENT_ID = d.DEPARTMENT_ID INNER
JOIN locations l
ON d.LOCATION_ID = l.LOCATION_ID
WHERE l.CITY = 'Toronto';

6.显示雇员的 last name 和 employee number 连同他们的经理的 last name 和manager number。列标签分别为 Employee、 Emp#、Manager 和 Mgr#

SELECT
w.LAST_NAME empname,w.DEPARTMENT_ID
empid,m.LAST_NAME mgrname,m.EMPLOYEE_ID mgrid
FROM employees w INNER JOIN employees m
ON w.MANAGER_ID = m.EMPLOYEE_ID;

聚合函数

聚合函数介绍

聚合函数也称之为多行函数,组函数或分组函数。聚合函数不象单 行函数,聚合函数对行的分组进行操作,对每组给出一个结果。如 果在查询中没有指定分组,那么聚合函数则将查询到的结果集视为 一组。

聚合函数类型

image-20220112140438382

聚合函数说明:

image-20220112140458508

聚合函数使用方式

image-20220112140512806

使用聚合函数的原则
  • DISTINCT 使得函数只考虑不重复的值;
  • 所有聚合函数忽略空值。为了用一个值代替空值,用 IFNULL 或 COALESCE 函数。
AVG 和 SUM 函数

AVG(arg)函数 对分组数据做平均值运算。

arg:参数类型只能是数字类型。

SUM(arg)函数 对分组数据求和。

arg:参数类型只能是数字类型。

示例: 计算员工表中工作编号含有REP的工作岗位的平均薪水与薪水总 和。

SELECT AVG(salary),SUM(salary)
FROM employees
WHERE job_id LIKE '%REP%';
MIN 和 MAX 函数
MIN(arg)函数

求分组中最小数据。 arg:参数类型可以是字符、数字、 日期。

MAX(arg)函数 求分组中最大数据。

arg:参数类型可以是字符、数字、 日期。

示例: 查询员工表中入职时间最短与最长的员工,并显示他们的入职时 间。

SELECT MIN(hire_date), MAX(hire_date) FROM
employees;
COUNT 函数

返回分组中的总行数。

  • COUNT 函数有三种格式: COUNT(*):返回表中满足 SELECT 语句的所有列的行数,包括 重复行,包括有空值列 的行
  • COUNT(expr):返回在列中的由 expr 指定的非空值的数。
  • COUNT(DISTINCT expr):返回在列中的由 expr 指定的唯一的 非空值的数。
使用 DISTINCT 关键字
  • COUNT(DISTINCT expr) 返回对于表达式 expr 非空并且值不相 同的行数
  • 显示 EMPLOYEES 表中不同部门数的值

示例一: 显示员工表中部门编号是80中有佣金的雇员人数。

SELECT COUNT(commission_pct) FROM employees
WHERE department_id = 80;

示例二: 显示员工表中的部门数。

SELECT COUNT(DISTINCT department_id) FROM
employees;
组函数和 Null 值

在组函数中使用 IFNULL 函数

SELECT AVG(IFNULL(commission_pct, 0)) FROM
employees;
数据分组(GROUP BY)

创建数据组

image-20220112141012383

创建数据组

在没有进行数据分组之前,所有聚合函数是将结果集作为一个大的 信息组进行处理。但是,有时,则需要将表的信息划分为较小的 组,可以用 GROUP BY 子句实现。

GROUP BY 子句语法

image-20220112141055858

原则
  • 使用 WHERE 子句,可以在划分行成组以前过滤行。
  • 如果有WHERE子句,那么GROUP BY 子句必须在WHERE的子句后面。
  • 在 GROUP BY 子句中必须包含列。
使用 GROUP BY 子句

image-20220112141139384

GROUP BY 子句

下面是包含一个 GROUP BY 子句 SELECT 语句的求值过程:

  • SELECT 子句指定要返回的列: 在 EMPLOYEES 表中的部门号 − GROUP BY 子句中指定分组的所有薪水的平均值 − FROM 子句指定数据库必须访问的表:EMPLOYEES 表。
  • WHERE 子句指定被返回的行。因为无 WHERE 子句默认情况下 所有行被返回。
  • GROUP BY 子句指定行怎样被分组。行用部门号分组,所以 AVG 函数被应用于薪水列,以计算每个部门的平均薪水。

示例: 计算每个部门的员工总数。

SELECT DEPARTMENT_ID, COUNT(*) FROM employees
GROUP BY DEPARTMENT_ID;

在多列上使用分组

image-20220112141334166

在组中分组

可以列出多个 GROUP BY 列返回组和子组的摘要结果。可以用 GROUP BY子句中的列的顺序确定结果的默认排序顺序。下面是图 片中的 SELECT 语句中包含一个 GROUP BY 子句时的求值过程:

  • SELECT 子句指定被返回的列: − 部门号在 EMPLOYEES 表中 − Job ID 在 EMPLOYEES 表中 − 在 GROUP BY 子句中指定的组中所有薪水的合计
  • FROM 子句指定数据库必须访问的表:EMPLOYEES 表
  • GROUP BY 子句指定你怎样分组行:

− 首先,用部门号分组行。 − 第二,在部门号的分组中再用 job ID 分组行。

− 首先,用部门号分组行。 − 第二,在部门号的分组中再用 job ID 分组行。

示例: 计算每个部门的不同工作岗位的员工总数。

SELECT e.DEPARTMENT_ID, e.JOB_ID,COUNT(*)FROM
employees e
GROUP BY e.DEPARTMENT_ID,e.JOB_ID;

约束分组结果(HAVING)

image-20220112141518382

HAVING 子句

HAVING 子句是对查询出结果集分组后的结果进行过滤。

约束分组结果

用 WHERE 子句约束选择的行,用 HAVING 子句约束组。为了找到 每个部门中的最高薪水,而且只显示最高薪水大于 $10,000 的那些 部门,可以象下面这样做:

  • 用部门号分组,在每个部门中找最大薪水。
  • 返回那些有最高薪水大于 $10,000 的雇员的部门
SELECT department_id, MAX(salary) FROM
employees GROUP BY department_id HAVING
MAX(salary)>10000 ;

HAVING子句语法

image-20220112141629223

示例: 显示那些合计薪水超过 13,000 的每个工作岗位的合计薪水。排除那 些JOB_ID中含有REP的工作岗位,并且用合计月薪排序列表。

SELECT job_id, SUM(salary) PAYROLL FROM
employees WHERE job_id NOT LIKE '%REP%'GROUP
BY job_id HAVING SUM(salary) > 13000 ORDER BY
SUM(salary);
练习

1.显示所有雇员的最高、最低、合计和平均薪水,列标签分别为: Max、Min、Sum 和 Avg。四舍五入结果为最近的整数。

SELECT
ROUND(MAX(e.SALARY)) max,ROUND(MIN(e.SALARY))
min,ROUND(SUM(e.SALARY)) sum ,
ROUND(AVG(e.SALARY)) avg
FROM employees e;

2.写一个查询显示每一工作岗位的人数。

SELECT
e.JOB_ID,COUNT(*)
FROM employees e
GROUP BY e.JOB_ID;

3.确定经理人数,不需要列出他们,列标签是 Number of Managers。提示:用MANAGER_ID列决定经理号。

SELECT
COUNT(DISTINCT e.MANAGER_ID)
FROM employees e;

4.写一个查询显示最高和最低薪水之间的差。

SELECT
MAX(e.SALARY) - MIN(e.SALARY)
FROM employees e;

5.显示经理号和经理付给雇员的最低薪水。排除那些经理未知的 人。排除最低薪水小于等于 $6,000 的组。按薪水降序排序输出。

SELECT e.MANAGER_ID,MIN(e.SALARY)
FROM employees e
WHERE e.MANAGER_ID is not null
GROUP BY e.MANAGER_ID
HAVING min(e.SALARY) > 6000
ORDER BY min(e.SALARY) desc;

6.写一个查询显示每个部门的名字、地点、人数和部门中所有雇员 的平均薪水。四舍五入薪水到两位小数。

SELECT
d.DEPARTMENT_NAME,d.LOCATION_ID,COUNT(*),ROUN
D(AVG(e.SALARY))
FROM employees e,departments d
where e.DEPARTMENT_ID = d.DEPARTMENT_ID
GROUP BY d.DEPARTMENT_NAME,d.LOCATION_ID
子查询
子查询介绍

image-20220112142012749

用子查询解决问题

假如要写一个查询来找出挣钱比 Abel 的薪水还多的人。为了解决这 个问题,需要两个查询:一个找出 Abel 的收入,第二个查询找出收 入高于 Abel 的人。可以用组合两个查询的方法解决这个问题。内查 询或子查询返回一个值给外查询或主查询。使用一个子查询相当于 执行两个连续查询并且用第一个查询的结果作为第二个查询的搜索 值。

image-20220112142036515

子查询 子查询是一个 SELECT 语句,它是嵌在另一个 SELECT 语句中的子 句。使用子查询可以用简单的语句构建功能强大的语句。 可以将子查询放在许多的 SQL 子句中,包括:

  • WHERE 子句
  • HAVING 子句
  • FROM 子句

使用子查询

image-20220112142123440

使用子查询的原则
  • 子查询放在圆括号中。
  • 将子查询放在比较条件的右边。
  • 在单行子查询中用单行运算符,在多行子查询中用多行运算符。
子查询类型

image-20220112142200774

示例: 查询与Fox同一部门的同事,并显示他们的名字与部门ID。

select e.LAST_NAME,e.DEPARTMENT_ID FROM
employees e
where e.DEPARTMENT_ID =
(select e1.DEPARTMENT_ID from employees e1
where e1.last_name = 'Fox');
单行子查询

image-20220112142240630

单行子查询

单行子查询是从内查询返回一行的查询。在该子查询类型中用一个 单行操作符。

示例: 查询 Fox的同事,但是不包含他自己。

select   empl.last_name   from   employees  
empl   where   empl.department_id   =  
(select e.department_id from employees e
where e.last_name = 'Fox') and empl.last_name
<> 'Fox';
多行子查询

image-20220112142322115

多行子查询

子查询返回多行被称为多行子查询。对多行子查询要使用多行运算 符而不是单行运 算符。

使用ANY运算符

image-20220112142353310

ANY 运算符

ANY 运算符比较一个值与一个子查询返回的每一个值。

  • < ANY 意思是小于最大值。 >ANY 意思是大于最小值. = ANY 等同于 IN。

使用ALL运算符

image-20220112142502090

ALL 运算符比较一个值与子查询返回的每个值。

< ALL 意思是小于最小值。 > ALL 意思是大于最大值,

NOT 运算符可以与 IN运算符一起使用。

子查询中的空值

image-20220112142534937

内查询返回的值含有空值,并因此整个查询无返回行,原因是用大 于、小于或不等于比较Null值,都返回null。所以,只要空值可能是 子查询结果集的一部分,就不能用 NOT IN 运算符。NOT IN 运算符 相当于 <> ALL。

注意,空值作为一个子查询结果集的一部分,如果使用 IN 操作符的 话,不是一个问题。IN 操作符相当于 =ANY。

SELECT emp.last_name FROM employees emp WHERE
emp.employee_id IN (SELECT mgr.manager_id
FROM employees mgr);

示例: 查找各部门收入为部门最低的那些雇员。显示他们的名字,薪水以 及部门 ID。

select 
em.last_name,em.salary,em.department_id  from
employees em  where em.salary in(select
min(e.salary) from employees e group by
e.department_id);
练习

1.写一个查询显示与 Zlotkey 在同一部门的雇员的 last name 和 hire date,结果中不包括 Zlotkey。

SELECT
e1.LAST_NAME,e1.HIRE_DATE
FROM employees e1
where e1.DEPARTMENT_ID =
(select e.DEPARTMENT_ID FROM employees e
where e.LAST_NAME ='Zlotkey')
AND e1.LAST_NAME <> 'Zlotkey';

2.创建一个查询显示所有其薪水高于平均薪水的雇员的雇员号和名 字。按薪水的升序排序。

SELECT
e1.EMPLOYEE_ID,e1.LAST_NAME
FROM employees e1
WHERE e1.SALARY >
(select AVG(e.SALARY) from employees e)
ORDER BY e1.SALARY;

3.写一个查询显示所有工作在有任一雇员的名字中包含一个 u 的部 门的雇员的雇员号和名字。

SELECT
e1.EMPLOYEE_ID,e1.LAST_NAME
FROM employees e1
WHERE e1.DEPARTMENT_ID IN
(SELECT e.DEPARTMENT_ID FROM employees e
WHERE e.LAST_NAME like '%u%')

4.显示所有部门地点号 (department location ID ) 是 1700 的雇员 的 last name、department number 和 job ID。

SELECT
e.LAST_NAME,e.DEPARTMENT_ID,e.JOB_ID
FROM employees e
WHERE e.DEPARTMENT_ID IN
(SELECT
d.DEPARTMENT_ID
FROM departments d
WHERE d.LOCATION_ID = 1700)

5.显示每个向 King 报告的雇员的名字和薪水。

SELECT
e1.LAST_NAME,e1.SALARY
FROM employees e1
where e1.MANAGER_ID IN
(select e.EMPLOYEE_ID from employees e where
e.LAST_NAME ='King')

6.显示在 Executive 部门的每个雇员的 department number、last name 和 job ID。

SELECT
e.DEPARTMENT_ID,e.LAST_NAME,e.JOB_ID
FROM employees e
WHERE e.DEPARTMENT_ID =
(select d.DEPARTMENT_ID FROM departments d
WHERE d.DEPARTMENT_NAME = 'Executive');
MySQL中的索引
索引介绍

索引是对数据库表中的一列或多列值进行排序的一种结构,使用索 引可以快速访问数据库表中的特定信息。索引是一种特殊的文件, 它们包含着对数据表里所有记录的位置信息。更通俗的说,数据库 索引好比是一本书前面的目录,能加快数据库的查询速度。MySQL 索引的建立对于MySQL 的高效运行是很重要的,索引可以大大提高 MySQL 的检索速度。

索引的作用

索引相当于图书上的目录,可以根据目录上的页码快速找到所需的 内容,提高性能(查询速度)。

索引优点:
1 通过创建唯一性索引,可以保证数据库表中的每一行数据的唯一性;
2 可以加快数据的检索速度;
3 可以加速表与表之间的连接;
4 在使用分组和排序进行检索的时候,可以减少查询中分组和排序的时间;

索引缺点
1 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加;
2 索引需要占用物理空间,数据量越大,占用空间越大;
3 会降低表的增删改的效率,因为每次增删改索引都需要进行动态维护;
什么时候需要创建索引
1 频繁作为查询条件的字段应该创建索引;
2 查询中排序的字段创建索引将大大提高排序的速度(索引就是排序加快速查找);
3 查询中统计或者分组的字段;
什么时候不需要创建索引
1
2 where条件里用不到的字段,不创建索引;
3 表记录太少,不需要创建索引;
4 经常增删改的表;
数据重复且分布平均的字段,因此为经常查询的和经常排序的字段建立索引。注意某些数据包含大
量重复数据,因此他建立索引就没有太大的效果,例如性别字段,只有男女,不适合建立索引;

MySQL中的索引类型
普通索引:
最基本的索引,它没有任何限制。
唯一索引:
索引列的值必须唯一,但允许有空值,如果是组合索引,则列值
的组合必须唯一。
主键索引:
特殊的索引,唯一的标识一条记录,不能为空,一般用primary
key来约束。
联合索引:
在多个字段上建立索引,能够加速查询到速度。
普通索引:

最基本的索引,它没有任何限制。 唯一索引: 索引列的值必须唯一,但允许有空值,如果是组合索引,则列值 的组合必须唯一。 主键索引: 特殊的索引,唯一的标识一条记录,不能为空,一般用primary key来约束。 联合索引: 在多个字段上建立索引,能够加速查询到速度。

创建索引时需要注意: 如果指定单列索引长度,length 必须小于这个字段所允许的最 大字符个数。

查询索引

SHOW INDEX FROM table_name; 
直接创建索引
CREATE INDEX index_name ON
table(column(length));

示例:为 emp3 表中的 name 创建一个索引,索引名为 emp3_name_index;

create index emp3_name_index ON emp3(name);
修改表添加索引
ALTER TABLE table_name ADD INDEX index_name
(column(length));

示例: 修改 emp3 表,为 addrees 列添加索引,索引名为 emp3_address_index;

alter table emp3 add index
emp3_address_index(address);
创建表时指定索引列
CREATE TABLE `table` (
COLUMN TYPE ,
PRIMARY KEY (`id`),
INDEX index_name (column(length))
);

示例:创建 emp4 表,包含 emp_id,name,address 列, 同时为 name 列 创建索引 ,索引名为 emp4_name_index。

create  table emp4(emp_id  int  primary  key
auto_increment,name  varchar(30),address
varchar(50),index emp4_name_index(name));
删除索引
DROP INDEX indexname ON tablename;

示例: 删除 mep3 表中索引名为 emp3_address_index 的索引。

drop index emp3_address_index on emp3;

唯一索引

唯一索引与普通索引类似,不同的就是: 索引列的值必须唯一,但 允许有空值。

创建唯一索引
CREATE UNIQUE INDEX indexName ON
table(column(length));

示例: 为 emp 表中的 name 创建一个唯一索引,索引名为 emp_name_index。

create unique index emp_name_index on
emp(name);
修改表添加唯一索引
ALTER TABLE table_name ADD UNIQUE indexName
(column(length));

示例: 修改 emp 表,为 salary 列添加唯一索引,索引名为 emp_salary_index。

alter table emp add unique
emp_salary_index(salary);
创建表时指定唯一索引
CREATE TABLE `table` (
COLUMN TYPE ,
PRIMARY KEY (`id`),
UNIQUE index_name (column(length))
);

示例: 创建 emp5 表,包含 emp_id,name,address 列,同时为 name 列 创建唯一索引。索引名为 emp5_name_index。

create table emp5(emp_id int primary key
,name varchar(30),address varchar(30),unique
emp5_name_index(name));
主键索引

主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许 有空值。一般是在建表的时候同时创建主键索引。

修改表添加主键索引

ALTER TABLE 表名 ADD PRIMARY KEY(列名);

示例: 修改 emp 表为 employee_id 添加主键索引。

alter table emp add primary key(employee_id);
创建表时指定主键索引
CREATE TABLE `table` (
COLUMN TYPE ,
PRIMARY KEY(column)
);

示例: 创建 emp6 表,包含 emp_id,name,address 列,同时为 emp_id 列创建主键索引。

create table emp6(employee_id int primary key
auto_increment,name varchar(20),address
varchar(50));
组合索引

组合索引是指使用多个字段创建的索引,只有在查询条件中使用了 创建索引时的第一个字段,索引才会被使用(最左前缀原则)。

最左前缀原则

就是最左优先。如: 我们使用表中的 name ,address ,salary 创建组合索引,那 么想要组合索引生效, 我们只能使用如下组合:

name/address/salary

name/address

name/

如果使用 addrees/salary 或者是 salary 则索引不会生效。

添加组合索引
ALTER TABLE table_name ADD INDEX index_name
(column(length),column(length));

示例: 修改 emp6 表,为 name ,address 列创建组合索引。

alter table emp6 add index
emp6_index_n_a(name,address);
创建表时创建组合索引
CREATE TABLE `table` (
COLUMN TYPE ,
INDEX index_name
(column(length),column(length))
);

示例: 创建 emp7 表,包含 emp_id,name,address 列,同时为 name,address 列创建组合索引。

create table emp7(emp_id int primary key
auto_increment  ,name varchar(20),address
varchar(30),index
emp7_index_n_a(name,address));
MySQL事务
事务简介

事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执 行,要么完全地不执行。

事务定义(Transaction)

  • 事务是一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业 务,该业务就是一个最小的工作单元)
  • 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML 语句的个数不同
事务四大特征(ACID)
  • 原子性(ATOMICITY) 事务中的操作要么都不做,要么就全做。

  • 一致性(CONSISTENCY) 一个事务应该保护所有定义在数据上的不变的属性(例如完整性 约束)。在完成了一个成功的事务时,数据应处于一致的状态。

  • 隔离性(ISOLATION) 一个事务的执行不能被其他事务干扰。

  • 持久性(DURABILITY) 一个事务一旦提交,它对数据库中数据的改变就应该是永久性 的。

事务类型
  • 显式事务 需要我们手动的提交或回滚。 DML 语言中的所有操作都是显示事务操作。

  • 隐式事务 数据库自动提交不需要我们做任何处理,同时也不具备回滚性。 DDL、DCL 语言都是隐式事务操作

    使用事务

image-20220112144612874

示例一: 创建account账户表,包含id、卡号、用户名、余额。

create table account(
id int primary key auto_increment,
cardnum varchar(20) not null,
username varchar(30) not null,
balance double(10,2)
);

示例二: 向account表中插入两条数据。

insert into account(cardnum,username,balance)
VALUES('123456789',
'张三'
,2000);
insert into account(cardnum,username,balance)
VALUES('987654321',
'李四'
,2000);

示例三: 在一个事务中完成转账业务。

START TRANSACTION
update account set balance = balance-200
where cardnum = '123456789';
update account set balance = balance+200
where cardnum = '987654321';
select * from account;
-- 当我们关闭数据库重新打开后,张三和李四的账户余额并
没发生任何变化。  
-- 这是因为当我们使用“START TRANSACTION”开启一个
事务后,该事务的提交方式不再是自动的,  
-- 而是需要手动提交,而在这里,我们并没有使用事务提交
语句COMMIT,  
-- 所以对account表中数据的修改并没有永久的保存到数
据库中,也就是说我们的转账事务并没有执行成功  
-- 提交转账事务  
commit;
-- 事务的回滚让数据库恢复到了执行事务操作前的状
态。  
-- 需要注意的是事务的回滚必须在事务提交之前,因为事务
一旦提交就不能再进行回滚操作。
rollback;
事务的并发问题 脏读(读取未提交数据)

指一个事务读取了另外一个事务未提交的数据。 A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行 回滚操作,那么A事务读取到的数据就是脏数据。

image-20220112144827296

不可重复读(前后多次读取,数据内容不一致)

在一个事务内读取表中的某一行数据,多次读取结果不同。 事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据 需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取 了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为 30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30 岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读 取到重复的数据,成为不可重复读。

image-20220112144859291

幻读(前后多次读取,数据总量不一致)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取数 量总量不一致。 事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据 总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务 A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白 无故的多了几条数据,成为幻读。

image-20220112144928023

事务的隔离级别

事务的隔离级别用于决定如何控制并发用户读写数据的操作。数据 库是允许多用户并发访问的,如果多个用户同时开启事务并对同一 数据进行读写操作的话,有可能会出现脏读、不可重复读和幻读问 题,所以MySQL中提供了四种隔离级别来解决上述问题。

事务的隔离级别从低到高依次为:

READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

隔离级别越低,越能支持高并发的数据库操作。

image-20220112145021278

查看MySQL默认事务隔离级别
SELECT @@transaction_isolation;
设置事务隔离级别

对当前session有效。

set session transaction isolation level read
uncommitted;
set session transaction isolation level read
committed;
set session transaction isolation level
repeatable read;
set session transaction isolation level
serializable;
MySQL的用户管理

MySQL 是一个多用户的数据库系统,按权限,用户可以分为两种: root 用户,超级管理员,和由 root 用户创建的普通用户。

用户管理
创建用户
CREATE USER username IDENTIFIED BY
'password';
查看用户
SELECT USER,HOST FROM mysql.user;

示例: 创建一个 u_sxt 的用户,并查看创建是否成功。

create user u_sxt IDENTIFIED by 'sxt';
select user,host from mysql.user;
权限管理

新用户创建完后是无法登陆的,需要分配权限。 GRANT 权限 ON 数据库.表 TO 用户名@登录主机 IDENTIFIED BY "密码"

登陆主机:

image-20220112145242090

权限列表

image-20220112145312428

image-20220112145332395

image-20220112145343320

GRANT ALL PRIVILEGES ON *.* TO
'username'@'localhost' IDENTIFIED BY
'password'

示例: 为 u_sxt 用户分配只能查询 bjsxt 库中的 emp 表,并且只能在本机 登陆的权限。

grant select ON bjsxt.emp to
'u_sxt'@'localhost' IDENTIFIED by 'sxt';
刷新权限

每当调整权限后,通常需要执行以下语句刷新权限。

FLUSH PRIVILEGES;
删除用户
DROP USER username@localhost;

示例:删除 u_sxt 用户。

drop user 'u_sxt'@'localhost';

MySQL分页查询

MySQL 分页查询原则:

  • 在 MySQL 数据库中使用 LIMIT 子句进行分页查询。

  • MySQL 分页中开始位置为 0。

  • 分页子句在查询语句的最后侧。

LIMIT子句
SELECT 投影列 FROM 表名 WHERE 条件 ORDER BY
LIMIT 开始位置,查询数量;

示例: 查询雇员表中所有数据按 id 排序,实现分页查询,每次返回两条结 果。

select * from employees order by employees_id
limit 0,2;
LIMIT OFFSET子句
SELECT 投影列 FROM 表名 WHERE 条件 ORDER BY
LIMIT 查询数量 OFFSET 开始位置;

示例: 查询雇员表中所有数据按 id 排序,使用 LIMIT OFFSET 实现分页查 询,每次返回两条结果。

select * from employees order by employees_id
limit 2 offset 4;
posted @   齐天_大圣  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示