Mysql数据库
1.数据库的介绍
1.1登录mysql数据库
mysql -u 用户名 -p密码
mysql -u 用户名 -p 回车输入密码
mysql --host=ip地址 --user=用户名 --password=密码
2.sql语句
2.1分类
数据定义语言 ddl
定义数据库的对象:数据库,表,列等
关键字:create ,alter ,drop
数据操作语言 dml
数据库中的表做更新
关键字:insert ,delete ,update
数据控制语言 dcl
数据库的访问权限和安全级别做出限制
数据查询语言 dql
查询数据库中表的记录
关键字:select ,from where
2.2sql数据类型
分类 类型名称 说明 整数类型 tinyInt 很小的整数 smallint 小的整数 mediumint 中等大小的整数 int(integer) 普通大小的整数 小数类型 float 单精度浮点数 double 双精度浮点数 decimal(m,d) 压缩严格的定点数 decimal(10,2) 日期类型 year YYYY 1901~2155 time HH:MM:SS -838:59:59~838:59:59 date YYYY-MM-DD 1000-01-01~9999-12-3 datetime YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59 timestamp YYYY-MM-DD HH:MM:SS 19700101 00:00:01 UTC~2038-01-19 03:14:07UTC 文本、二进制类型 char(m) m为0~255之间的整数定长 char(10) tom varchar(m) m为0~65535之间的整数变长 varchar(10) tom tinyblob 允许长度0~255字节 blob 允许长度0~65535字节 mediumblob 允许长度0~167772150字节 longblob 允许长度0~4294967295字节 tinytext 允许长度0~255字节 text 允许长度0~65535字节 mediumtext 允许长度0~167772150字节 longtext 允许长度0~4294967295字节 varbinary(m) 允许长度0~M个字节的变长字节字符串 binary(m) 允许长度0~m个字节的定长字节字符串
3.ddl之数据库的操作
3.1创建数据库
create database 数据库名; #直接创建
create database if not exists 数据库名 #如果不存在则直接创建
create database 数据库名 character set 字符集 #创建时设置字符集
3.2查看mysql服务器中所有的数据库
show databases;
3.3删除数据库
drop database 数据库名
3.4使用数据库
use 数据库名
3.5查看正在使用的数据库
select database();
4.ddl之表的操作
4.1创建表
create table if not exists 表名(
字段名 类型(长度) [约束],
字段名 类型(长度) [约束],
...
);
类型:
varchar(n)字符串
int 整形
double浮点
date 时间
timestamp时间戳
约束:
primary key 主键,被主键修饰字段中的数据,不能重复、不能为null。
###创建分类表
CREATE TABLE category (
cid varchar(20) primary key,#分类ID
cname VARCHAR(100) #分类名称
);
4.2查看数据库中所有表
show tables
4.3查看表的结构
desc 表名
4.4删除表
drop table 表名
4.5修改表的结构
#为表添加一个新的字段
alter table 表名 add 新的字段名 约束类型
#修改表的列名
alter table 表名 change 旧列名 新列名 约束类型
#删除表的列
alter table 表名 drop 要删除的列
#修改表名
rename table 表名 to 新表名
5.dml数据操作语言
5.1插入表记录
#想表中插入某些字段
insert into 表名 (字段一,字段二,字段三)values (值1,值2,值3)
#向表中插入所有字段
insert into 表名 values(值1,值2,值3)
#例如
INSERT INTO category(cid,cname) VALUES('c001','电器');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
INSERT INTO category(cid,cname) VALUES('c004','书籍');
INSERT INTO category(cid) VALUES('c005');
insert into category values('06','玩具'),('07','蔬菜');
5.2更新表的记录
#更新表的所有指定字段
update 表名 set 字段值=值,字段名=值;
#更新条件的指定字段
update 表名 set 字段名=值,字段名=值 where 条件;
5.3删除表的记录
#逻辑删除,磁盘删除
delete from 表名[where 条件]
truncate table 表名
#delete是一条一条的删除数据,不会清空auto_increment自动记录数
#truncate直接将表删除,auto_increment记录为零,重新开始‘
6.sql约束
6.1主键约束
*PRIMARY KEY* 约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值。
主键列不能包含 NULL 值。
每个表都应该有一个主键,并且每个表只能有一个主键。
#添加主键约束
#在创建表的时候,在字段申明描述的时候,申明指定字段为主键
CREATE TABLE Persons1
(
Id int PRIMARY KEY,
LastName varchar(255),
FirstName varchar(255),
)
#创建表的时候,在constraint约束区域,声明指定字段为主键
CREATE TABLE Persons2
(
FirstName varchar(255),
LastName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (FirstName, LastName)
)
#删除主键约束
alter table 表名 drop primary key
#自动增长序列
##希望每次插入新纪录时,数据库自动维护生成字段值
##auto_increment(自动增长列)关键字,自动增长列必须是整形
CREATE TABLE Persons4
(
Id int PRIMARY KEY AUTO_INCREMENT,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
##向persons添加数据时,可以不为Id字段设置值,也可以设置成null,数据库将自动维护主键值
INSERT INTO Persons (FirstName,LastName) VALUES ('Bill','Gates')
INSERT INTO Persons (Id,FirstName,LastName) VALUES (NULL,'Bill','Gates')
##扩展:默认AUTO_INCREMENT 的开始值是 1,如果希望修改起始值,请使用下列 SQL 语法:
alter table 表名 auto_increment=?
ALTER TABLE Persons AUTO_INCREMENT=100
6.2唯一约束
UNIQUE 约束唯一标识数据库表中的每条记录。
UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。
PRIMARY KEY 拥有自动定义的 UNIQUE 约束。
请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。
#创建表的时候,在字段描述处申明
CREATE TABLE Persons
(
Id int UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
6.3非空约束
NOT NULL 约束强制列不接受 NULL 值。
NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
下面的 SQL 语句强制 “Id” 列和 “LastName” 列不接受 NULL 值:
CREATE TABLE Persons5
(
Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
7.dql数据查询语言
#创建商品表:
create table product(
pid int primary key,
pname varchar(20),
price double,
category_id varchar(32)
);
#插入数据
INSERT INTO product(pid,pname,price,category_id) VALUES(1,'联想',5000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(2,'海尔',3000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(3,'雷神',5000,'c001');
INSERT INTO product(pid,pname,price,category_id) VALUES(4,'杰克琼斯',800,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(5,'真维斯',200,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(6,'花花公子',440,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(7,'劲霸',2000,'c002');
INSERT INTO product(pid,pname,price,category_id) VALUES(8,'香奈儿',800,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(9,'相宜本草',200,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(10,'面霸',5,'c003');
INSERT INTO product(pid,pname,price,category_id) VALUES(11,'好想你枣',56,'c004');
INSERT INTO product(pid,pname,price,category_id) VALUES(12,'香飘飘奶茶',1,'c005');
INSERT INTO product(pid,pname,price,category_id) VALUES(13,'海澜之家',1,'c002');
7.1语法
select [distinct]
* |列名,列名
from 表
where 条件
7.2 简单查询
#1.查询所有的商品.
select * from product;
#2.查询商品名和商品价格.
select pname,price from product;
#3.别名查询.使用的关键字是as(as可以省略的).
#3.1表别名:
select * from product as p;
#3.2列别名:
select pname as pn from product;
#4.去掉重复值.
select distinct price from product;
#5.查询结果是表达式(运算查询):将所有商品的价格+10元进行显示.
select pname,price+10 from product;
7.3 条件查询
比较运算符 | > < <= >= = <> != | 大于、小于、大于(小于)等于、不等于 |
---|---|---|
BETWEEN …AND… | 显示在某一区间的值(含头含尾) | |
IN(set) | 显示在in列表中的值,例:in(100,200) | |
LIKE ‘张%’LIKE ‘%涛%’ | 模糊查询,Like语句中,%代表零个或多个任意字符,_代表一个字符,例如:first_name like ‘_a%’; | |
IS NULL IS NOT NULL | 判断是否为空 | |
逻辑运算符 | and | 多个条件同时成立 |
or | 多个条件任一成立 | |
not | 不成立,例:where not(salary>100); |
#查询商品名称为“花花公子”的商品所有信息:
SELECT * FROM product WHERE pname = '花花公子';
#查询价格为800商品
SELECT * FROM product WHERE price = 800;
#查询价格不是800的所有商品
SELECT * FROM product WHERE price != 800;
SELECT * FROM product WHERE price <> 800;
SELECT * FROM product WHERE NOT(price = 800);
#查询商品价格大于60元的所有商品信息
SELECT * FROM product WHERE price > 60;
#查询商品价格在200到1000之间所有商品
SELECT * FROM product WHERE price >= 200 AND price <=1000;
SELECT * FROM product WHERE price BETWEEN 200 AND 1000;
#查询商品价格是200或800的所有商品
SELECT * FROM product WHERE price = 200 OR price = 800;
SELECT * FROM product WHERE price IN (200,800);
#查询含有'霸'字的所有商品
SELECT * FROM product WHERE pname LIKE '%霸%';
#查询以'香'开头的所有商品
SELECT * FROM product WHERE pname LIKE '香%';
#查询第二个字为'想'的所有商品
SELECT * FROM product WHERE pname LIKE '_想%';
#查询没有分类的商品
SELECT * FROM product WHERE category_id IS NULL;
#查询有分类的商品
SELECT * FROM product WHERE category_id IS NOT NULL;
7.4排序查询
通过order by语句,可以将查询出的结果进行排序。暂时放置在select语句的最后。
SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
ASC 升序 (默认)
DESC 降序
#1.使用价格排序(降序)
SELECT * FROM product ORDER BY price DESC;
#2.在价格排序(降序)的基础上,以分类排序(降序)
SELECT * FROM product ORDER BY price DESC,category_id DESC;
#3.显示商品的价格(去重复),并排序(降序)
SELECT DISTINCT price FROM product ORDER BY price DESC;
7.5聚合查询
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值。
今天我们学习如下五个聚合函数:
聚合函数 | 作用 |
---|---|
count() | 统计指定列不为NULL的记录行数; |
sum() | 计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0 |
max() | 计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算; |
min() | 计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算; |
avg() | 计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0 |
#1 查询商品的总条数
SELECT COUNT(*) FROM product;
#2 查询价格大于200商品的总条数
SELECT COUNT(*) FROM product WHERE price > 200;
#3 查询分类为'c001'的所有商品的总和
SELECT SUM(price) FROM product WHERE category_id = 'c001';
#4 查询分类为'c002'所有商品的平均价格
SELECT AVG(price) FROM product WHERE category_id = 'c002';
#5 查询商品的最大价格和最小价格
SELECT MAX(price),MIN(price) FROM product;
7.6分组查询
分组查询是指使用group by字句对查询信息进行分组。
格式:
SELECT 字段1,字段2… FROM 表名 GROUP BY分组字段 HAVING 分组条件;
分组操作中的having子语句,是用于在分组后对数据进行过滤的,作用类似于where条件。
*having与where的区别:*
1).having是在分组后对数据进行过滤.,where是在分组前对数据进行过滤
2).having后面可以使用分组函数(统计函数),where后面不可以使用分组函数。
#1 统计各个分类商品的个数
SELECT category_id ,COUNT(*) FROM product GROUP BY category_id ;
#2 统计各个分类商品的个数,且只显示个数大于1的信息
SELECT category_id ,COUNT(*) FROM product GROUP BY category_id HAVING COUNT(*) > 1;
7.7分页查询
分页查询在项目开发中常见,由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式。例如数据共有30条,每页显示5条,第一页显示1-5条,第二页显示6-10条。
SELECT** 字段1,字段2... **FROM** 表明 **LIMIT** M,N
M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数
N: 整数,表示查询多少条数据
**SELECT** 字段1,字段2... **FROM** 表明 **LIMIT** 0,5
**SELECT** 字段1,字段2... **FROM** 表明 **LIMIT** 5,5
\#查询product表的前5条记录
SELECT * FROM product LIMIT 0,5
7.8 insert into select语句
从一个表中复制数据到另外一个已经存在的表中
INSERT INTO table2
SELECT column_name(s)
FROM table1;
create table product2(
pid int primary key,
pname varchar(20),
price double
);
insert into product2 select pid,pname,price from product where category_id = 'c001';
8.多表操作
8.1 表与表的关系
一对一
一对多
多对多
8.2外键约束
#添加外键约束
alter table 从表 add 外键名称 foreign key (从表的外键字段名)references 主表(主表的主键)
外键的目的:保证数据的完整性
8.3一对多的操作
###创建分类表
create table category(
cid varchar(32) PRIMARY KEY ,
cname varchar(100) #分类名称
);
# 商品表
CREATE TABLE products (
pid varchar(32) PRIMARY KEY ,
name VARCHAR(40) ,
price DOUBLE ,
category_id varchar(32)
);
#添加外键约束
alter table products add products_fk foreign key (category_id) references category(cid)
#添加数据
#1 向分类表中添加数据
INSERT INTO category (cid ,cname) VALUES('c001','服装');
#2 向商品表添加普通数据,没有外键数据,默认为null
INSERT INTO products (pid,pname) VALUES('p001','商品名称');
#3 向商品表添加普通数据,含有外键信息(category表中存在这条数据)
INSERT INTO products (pid ,pname ,category_id) VALUES('p002','商品名称2','c001');
#4 向商品表添加普通数据,含有外键信息(category表中不存在这条数据) -- 失败,异常
INSERT INTO products (pid ,pname ,category_id) VALUES('p003','商品名称2','c999');
#5 删除指定分类(分类被商品使用) -- 执行异常
DELETE FROM category WHERE cid = 'c001';
9多表查询
9.1数据准备
CREATE TABLE category (
cid VARCHAR(32) PRIMARY KEY ,
cname VARCHAR(50)
);
CREATE TABLE products(
pid VARCHAR(32) PRIMARY KEY ,
pname VARCHAR(50),
price INT,
flag VARCHAR(2), #是否上架标记为:1表示上架、0表示下架
category_id VARCHAR(32),
CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid)
);
#分类
INSERT INTO category(cid,cname) VALUES('c001','家电');
INSERT INTO category(cid,cname) VALUES('c002','服饰');
INSERT INTO category(cid,cname) VALUES('c003','化妆品');
#商品
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','联想',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海尔',3000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p004','JACK JONES',800,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p005','真维斯',200,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p007','劲霸',2000,'1','c002');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p008','香奈儿',800,'1','c003');
INSERT INTO products (pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');
9.2多表查询
\1. 交叉连接查询(基本不会使用-得到的是两个表的乘积) [了解]
语法:select * from A,B;
\2. 内连接查询(使用的关键字 inner join – inner可以省略)
n 隐式内连接:select * from A,B where 条件;
n 显示内连接:select * from A inner join B on 条件;
\3. 外连接查询(使用的关键字 outer join – outer可以省略)
n 左外连接:left outer join
u select * from A left outer join B on 条件;
n 右外连接:right outer join
u select * from A right outer join B on 条件;
#1.查询哪些分类的商品已经上架
#隐式内连接
SELECT DISTINCT c.cname FROM category c , products p
WHERE c.cid = p.category_id AND p.flag = '1';
#内连接
SELECT DISTINCT c.cname FROM category c
INNER JOIN products p ON c.cid = p.category_id
WHERE p.flag = '1';
#2.查询所有分类商品的个数
#左外连接
INSERT INTO category(cid,cname) VALUES('c004','奢侈品');
SELECT cname,COUNT(category_id) FROM category c
LEFT OUTER JOIN products p
ON c.cid = p.category_id
GROUP BY cname;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ByfWmN8F-1645861791586)(C:\Users\XIAOMAHU\AppData\Roaming\Typora\typora-user-images\1645860092599.png)]
9.3子查询
子查询:一条select语句结果作为另一条select语法一部分(查询条件,查询结果,表等)。
select …查询字段 … from … 表… where … 查询条件
#3 子查询, 查询“化妆品”分类上架商品详情
#隐式内连接
SELECT p.* FROM products p , category c
WHERE p.category_id=c.cid AND c.cname = '化妆品';
#子查询
##作为查询条件
SELECT * FROM products p
WHERE p.category_id =
(
SELECT c.cid FROM category c
WHERE c.cname='化妆品'
);
##作为另一张表
SELECT * FROM products p ,
(SELECT * FROM category WHERE cname='化妆品') c
WHERE p.category_id = c.cid;
#查询“化妆品”和“家电”两个分类上架商品详情
SELECT * FROM products p
WHERE p.category_id in
(
SELECT c.cid FROM category c
WHERE c.cname='化妆品' or c.name='家电'
);
10mysql索引
10.1概念
索引是 MySQL 中一种十分重要的数据库对象。它是数据库性能调优技术的基础,常用于实现数据的快速检索。
索引就是根据表中的一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表,实质上是一张描述索引列的列值与原表中记录行之间一一对应关系的有序表。在 MySQL 中,通常有以下两种方式访问数据库表的行数据:
*1) 顺序访问*
顺序访问是在表中实行全表扫描,从头到尾逐行遍历,直到在无序的行数据中找到符合条件的目标数据。这种方式实现比较简单,但是当表中有大量数据的时候,效率非常低下。
*2) 索引访问*
索引访问是通过遍历索引来直接访问表中记录行的方式。使用这种方式的前提是对表建立一个索引,在列上创建了索引之后,查找数据时可以直接根据该列上的索引找到对应记录行的位置,从而快捷地查找到数据。索引存储了指定列数据值的指针,根据指定的排序顺序对这些指针排序。
例如,在学生基本信息表 students 中,如果基于 student_id 建立了索引,系统就建立了一张索引列到实际记录的映射表,当用户需要查找 student_id 为 12022 的数据的时候,系统先在 student_id 索引上找到该记录,然后通过映射表直接找到数据行,并且返回该行数据。因为扫描索引的速度一般远远大于扫描实际数据行的速度,所以采用索引的方式可以大大提高数据库的工作效率。
10.2索引分类
*根据存储方式的不同,MySQL 中常用的索引在物理上分为以下两类。*
*B-树索引*
B-树索引又称为 BTREE 索引,目前大部分的索引都是采用 B-树索引来存储的。B-树索引是一个典型的数据结构,基于这种树形数据结构,表中的每一行都会在索引上有一个对应值。因此,在表中进行数据查询时,可以根据索引值一步一步定位到数据所在的行。
*哈希索引*
哈希(Hash)一般翻译为“散列”,也有直接音译成“哈希”的,就是把任意长度的输入(又叫作预映射,pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。
HASH 索引不是基于树形的数据结构查找数据,而是根据索引列对应的哈希值的方法获取表的记录行。*根据索引的具体用途,MySQL 中的索引在逻辑上分为以下 3 类:*
*普通索引*
普通索引是最基本的索引类型,唯一任务是加快对数据的访问速度,没有任何限制。创建普通索引时,通常使用的关键字是 INDEX 或 KEY。
*唯一性索引*
唯一性索引是不允许索引列具有相同索引值的索引。如果能确定某个数据列只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它定义为一个唯一性索引。
创建唯一性索引的目的往往不是为了提高访问速度,而是为了避免数据出现重复。*主键索引*
主键索引是一种唯一性索引,即不允许值重复或者值为空,并且每个表只能有一个主键。主键可以在创建表的时候指定,也可以通过修改表的方式添加,必须指定关键字 PRIMARY KEY。
10.3索引操作
10.3.1普通索引
#创建索引
##直接创建
create index indexname on mytable(username(length));
##修改表的结果
alter table tablename add index indexname(columnname)
##创建标的时候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX indexName(username(length))
);
#查询索引
##查看表的所有索引
show index from 表名
##查看数据库的所有索引
select * from mysql.`innodb_index_stats` a where a.database_name='数据库名'
##查看某个表的索引
select * from mysql.`innodb_index_stats` a where a.database_name='数据库名' and a.table_name like '%表的名字%'
#删除索引
drop index [索引名] on 表名
alter table 表名 drop index 索引名
10.3.2唯一索引
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
#创建索引
##直接创建
create unique index 索引名 on 表名(username)
##修改表的结构
alter table 表名 add unique [索引名](username)
##创建表的时候指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);
#删除索引
drop index 索引名 on 表名
alter table 表名 drop index 索引名
10.3.3主键索引
10.4索引的使用原则
虽然索引可以加快查询速度,提高 MySQL 的处理性能,但是过多地使用索引也会造成以下弊端:
l 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
l 除了数据表占数据空间之外,每一个索引还要占一定的物理空间。如果要建立聚簇索引,那么需要的空间就会更大。
l 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。
l 对于那些在查询中很少使用或参考的列不应该创建索引。因为这些列很少使用到,所以有索引或者无索引并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度,并增大了空间要求。
11mysql开窗函数
mysql8.0版本支持
#语法结构
<开窗函数> over ([PARTITION by <列清单>]
Order by <排序用列清单>)
11.1开窗函数介绍
row_number(),rank(),dense_rank()这三个函数都是用于返回结果集的分组内每行的排名
*三者区别:*
****row_number:****不管排名是否有相同的,都按照顺序1,2,3……n
****rank:****排名相同的名次一样,同一排名有几个,后面排名就会跳过几次
****dense_rank****:排名相同的名次一样,且后面名次不跳跃
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1DQ6e84T-1645861791587)(C:\Users\XIAOMAHU\AppData\Roaming\Typora\typora-user-images\1645861603684.png)]
create table employee (empid int,ename varchar(20) ,deptid int ,salary decimal(10,2));
insert into employee values(1,'刘备',10,5500.00);
insert into employee values(2,'赵云',10,4500.00);
insert into employee values(2,'张飞',10,3500.00);
insert into employee values(2,'关羽',10,4500.00);
insert into employee values(3,'曹操',20,1900.00);
insert into employee values(4,'许褚',20,4800.00);
insert into employee values(5,'张辽',20,6500.00);
insert into employee values(6,'徐晃',20,14500.00);
insert into employee values(7,'孙权',30,44500.00);
insert into employee values(8,'周瑜',30,6500.00);
insert into employee values(9,'陆逊',30,7500.00);
#对employee表中按照deptid进行分组,并对每一组的员工按照薪资进行排名:
SELECT
empid,
ename,
deptid,
salary,
row_number() over (PARTITION BY deptid ORDER BY salary DESC) AS row_number1,
rank() OVER (PARTITION BY deptid ORDER BY salary desc) AS rank2,
dense_rank() OVER (PARTITION BY deptid ORDER BY salary desc) AS dense_rank3
FROM
employee;