Mysql数据库

目录

01 初始数据库

02 库相关操作

# 增
create database db1;
create database db2 charset='gbk';

# 查
show databases;   # 查所有
show create database db1; # 查单个
# 改
alter database db2 charset='utf8';

# 删
drop database db2;

# 修改表名
alter table 表名 rename 新表名;

# 增加字段
alter table 表名 add 字段名 字段类型(宽度) 约束条件;
alter table 表名 add 字段名 字段类型(宽度) 约束条件 first;  # 增加到最前面
alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名; # 增加到某字段后面
示例:
alter table xx add gender anum('male','female',others'') default 'male';
alter table xx add age int default 18 first;
alter table xx add qq int default 123456 after gender;

# 删除字段
alter table 表名 drop 字段名;
示例:
alter table xx drop qq;

# 修改字段
alter table 表名 modify 字段名 字段类型(宽度) 约束条件;
alter table 表名 change 旧字段名  新字段名 字段类型(宽度) 约束条件;
示例:
alter table xx modify age bigint default 18;
alter table xx change age age int default 19;

# 复制表
create table 表名 select * from 旧表;  不能复制主键 外键……

create table new_dep2 select * from dep where id>3;

03 表相关操作

# 查看当前所在库的名字
select database();

# 切换库
use text;

# 增
create table t1(id int,name,char(8),gender int);

# 查
show tables;  # 查看当前库下面所有的表名
show create table t1;
describe t1;  # 简写 desc t1;

# 改
alter table t1 modify name char(16);

# 删
drop table t1;

04 数据相关操作

# 一定先有库 有表 最好才能插入数据

# 增
insert into t1 values(1,'fx');
insert into t1 values(2,'xx'),(3,'xy'),(4,'pp');

# 查
select * from t1;
select name from t1;

# 改
update t1 set name='ll' where id = 4;

# 删
delete from t1;

05 存储引擎

  • innodb
    是mysql 5.5及之后版本默认存储引擎
    存储数据更加的安全
    创建表会生产两个文件:
    表结构文件
    表数据文件

  • myisam
    是mysql5.5之前版本默认存储引擎
    存储速度比innodb要快 但是我们更注重的是数据安全
    创建表会生产三个文件:
    表结构文件
    表数据文件
    表索引文件

  • memory
    内存引擎(数据存放在内存)断电数据丢失
    创建表会创建一个文件:
    表结构文件

  • blackhole
    无论存什么立马消失
    创建表会创建一个文件:
    表结构文件

# 查看所有的存储引擎
show engines;

# 不同的存储引擎在存储表的时候 异同点
create table t1(id int) engine=innodb;
create table t2(id int) engine=myisam;
create table t3(id int) engine=blackhole;
create table t4(id int) engine=memory;

# 存数据
insert into t1 values(1);
insert into t2 values(1);
insert into t3 values(1);
insert into t4 values(1);

06 创建表的完整语法

# 语法
create table 表名(
	字段名	字段类型(宽度)	约束条件,
	字段名	字段类型(宽度)	约束条件,
	字段名	字段类型(宽度)	约束条件
)
# 注意
1) 在通一张表中表字段不能重复
2)宽度和约束条件是可选的而字段名和字段类型是必须的
	约束条件写的话  也支持写多个
	字段名1 类型(宽度) 约束条件1 约束条件2.......,
	create table t5(id); 报错
3)最后一行不能有逗号
create table t6(
	id int,
	name char(8),
);   # 报错

07 严格模式

# 如何查看严格模式
show variables like "%mode";

模糊匹配/查询
	关键字 like
	%:匹配任意多个字符
	_:匹配任意单个字符

# 修改严格模式
	set session  只在当前窗口有效
	set global   全局有效

	set global sql_mode = 'STRICT_TRANS_TABLES';

    修改完之后 重新进入服务端即可

08 基本数据类型

整型
image

  • 分类
    TINYINT、SMALLINT、EDUIMINT、INT、BIGINT
  • 作用
    存储年龄、等级、id、号码等等
以tinyint
	是否有符号
		默认情况下是带符号的
	超出会如何
		超出现在只存最大可接收值

create table t9(id tinyint);
insert into t9 values(-129),(256);

# 约束条件之unsigned 无符号
create table t10(id tinyint unsigned);


create table t11(id int);
# int默认也是带符号的  
# 整型默认情况下都是带有符号的

# 针对整型 括号内的宽度到底是干嘛的
create table t12(id int(8));
insert into t12 values(123456789);

"""
特例:只有整型括号里面的数字不是表示限制位数
id int(8)
	如果数字没有超出8位 那么默认用空格填充至8位
	如果数字超出了8位 那么有几位就存几位(但是还是要遵守最大范围)
"""
create table t13(id int(8) unsigned zerofill);
# 用0填充至8位

# 总结
针对整型字段 括号内无需指定宽度 因为它默认的宽度以及足够显示所有的数据了

浮点型

  • 分类
    float、double、decimal
  • 作用
    身高、体重、薪资
float(255,30) # 总共255位,小数部分占30位
double(255,30) # 总共255位,小数部分占30位
decimal(65,30) # 总共65位 小数部分占30位

# 精确度验证
create table t1(id float(255,30));
create table t2(id double(255,30));
create table t3(id decimal(65,30));

insert into t1 values(1.111111111111111111111111111111);
insert into t2 values(1.111111111111111111111111111111);
insert into t3 values(1.111111111111111111111111111111);

float < double < decimal

字符类型

  • 分类
char
	定长
	char(4)  数据超过四个字符直接报错,不够四个字符空格补全。
varchar 
	变长
	varchar(4) 数据超过四个字符直接报错,不够有几个存几个

create table t9(name char(4));
create table t10(name varchar(4));

insert into t9 values('a');
insert into t10 values('a');

# 统计字段长度
select char_length(name) from t9;
select char_length(name) from t10;

"""
首先可以肯定的是 char硬盘上存的绝对是真正的数据 带有空格的
但是在显示的时候MySQL会自动将多余的空格剔除
"""
# 再次修改sql_mode 让MySQL不要做自动剔除操作
set global sql_mode = 'STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH';

# 再次统计字段长度
select char_length(name) from t9;
+-------------------+
| char_length(name) |
+-------------------+
|                 4 |
+-------------------+
1 row in set (0.00 sec)

select char_length(name) from t10;
+-------------------+
| char_length(name) |
+-------------------+
|                 1 |
+-------------------+
1 row in set (0.00 sec)

char与varchar对比

char
	优点:存取都很简单,直接按照固定的字符存取数据即可,存按照五个存,取按照五个取
	缺点:浪费空间


varchar
	优点:节省空间
	缺点:存取比较麻烦,存的时候需要制作抱头,取的时候也需要先读取抱头,之后才能读取真实数据

时间类型

  • 分类
    date:2022-3-29
    datetime: 2022-3-29 11:11:11
    time:11:11:11
    year:2022
create table student(id int,name varchar(16),born_year year,birth date,study_time time,reg_time datetime);

insert into student values(1,'xx','2022','2022-03-29','11:11:11','2022-03-29 11:11:11');
Query OK, 1 row affected (0.00 sec)

select * from student;
+------+------+-----------+------------+------------+---------------------+
| id   | name | born_year | birth      | study_time | reg_time            |
+------+------+-----------+------------+------------+---------------------+
|    1 | xx   |      2022 | 2022-03-29 | 11:11:11   | 2022-03-29 11:11:11 |
+------+------+-----------+------------+------------+---------------------+
1 row in set (0.00 sec)

枚举与集合类型

  • 分类
枚举(enum)	多选一
集合(set)	多选多
  • 具体使用
create table teacher(id int,name char(8),gender enum('male','female','others'),hobby set('read','xixi','hehe'));

insert into teacher values(1,'fx','male','read');

insert into teacher values(2,'xx','female','xixi,hehe');

insert into teacher values(3,'ll','others','xx'); #报错

09 约束条件

  • default 默认值
# 插入数据的时候可以指定字段
create table t2(id int,name char(8),gender enum('male','female','others'));

insert into t2(id,name) values(1,'fx');
insert into t2 values(2,'xx','female');

  • unique唯一
# 单例唯一
create table t3(id int unique,name char(8));

insert into t3 values(1,'fx');
insert into t3 values(1,'xx') # 报错

# 联合唯一
"""
ip和port
单个都可以重复 但是加载一起必须是唯一的
"""
create table t4(id int,ip char(16),port int,unique(ip,port));

insert into t4 values(1,'127.0.0.1',8080);
insert into t4 values(2,'127.0.0.1',8081);
insert into t4 values(3,'127.0.0.2',8080);
insert into t4 values(4,'127.0.0.1',8080);  报错
  • primary key主键
    """
    1.单单从约束效果上来看primary key等价于not null + unique
    非空且唯一!!!
    """
create table t5(id int primary key);
insert into t5 values(null) #报错
insert into t5 values(1),(2);
insert into t5 values(1),(2);  #报错

"""
2. 它除了有约束效果之外 它还是innodb存储引擎组织数据的依据
innodb存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录 能够帮助提升查询效率并且也是建表的依据
"""

# 1 一张表有且只要一个主键 如果你没有设置主键 那么会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键
create table t5(
id int,
name char(8),
age int not null unique,
addr int not null unique
);

desc t5;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)


# 2 如果表中没有主键也没有其他任何的非空且唯一字段  那么innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着无法使用它 就没发提升查询速度

# 3 一张表中通常都应该有一个主键字段 并且通常将id、uid、sid字段作为主键
# 单字段主键
create table t6(
id int primary key,
name char(16)
);

# 联合主键(多个字段联合起来作为表的主键 本质还是一个主键)
create table t7(
ip char(16),
port int,
primary key(ip,port)
);

"""
以后创建表的时候一定要加primary key
"""
  • auto_increment 自增
create table t9(
id int primary key auto_increment,
name char(16)
);
insert into t9(name) values('fx'),('xx'),('xy'));

 select * from t9;
+----+------+
| id | name |
+----+------+
|  1 | fx   |
|  2 | xx   |
|  3 | xy   |
+----+------+
3 rows in set (0.00 sec)


desc t9;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(16) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

# 注意 auto_increment通常是加在主键上 不能给普通字段加
create table t10(id int primary key auto_increment,name char(16) cid int auto_increment);
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 'cid int auto_increment)' at line 1

"""
结论:以后创建表的id(数据的唯一标识id、uid、cid)字段的时候
id int primary key auto_increment
"""

10 表与表之间建关系

image

"""
定义一张员工表 表中有很多字段
id name gender dep_name dep_desc
"""
# 1 该表的组织架构不是很清晰
# 2 浪费磁盘空间
# 3 数据的扩展性极差

# 如何优化?
"""
上述问题就类似于你将所有的代码都写在一个py文件,冗余性差,将员工表拆分 员工表和部门表
"""
外键
"""
外键就是用来帮助我们建立表与表之间关系的
foreign key
"""
表关系
表与表之间有四种关系:
	1、一对多关系(一对多、多对一都叫一对多)
	2、多对多关系
	3、一对一关系
	4、没有关系
一对多关系

"""
判断表与表关系的时候 前期不熟悉的情况下  换位思考 分别站在两张表的角度考虑

员工表与部门表为例
	先站在员工表
		思考一个员工是否能对应多个部门(不能)
	站在部门表
		一个部门是否能对应多个员工(能)
	员工表和部门表是单向的一对多
	所以表关系是一对多
"""
foreign key
	1 一对多关系   外键字段建在多的一方
	2 在创建表的时候 一定先建被关联表
	3 在录入数据的时候 也必须先录入被关联表

# sql语句建立关系
create table dep(
id int primary key auto_increment,
dep_name char(8),
dep_desc char(8),
);

create table users(
id int primary key auto_increment,
name char(8),
gender  enum('male','female','others')
dep_id int,
foreign key(dep_id) references dep(id)
);
desc dep;
+----------+---------+------+-----+---------+----------------+
| Field    | Type    | Null | Key | Default | Extra          |
+----------+---------+------+-----+---------+----------------+
| id       | int(11) | NO   | PRI | NULL    | auto_increment |
| dep_name | char(8) | YES  |     | NULL    |                |
| dep_desc | char(8) | YES  |     | NULL    |                |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

desc users;
+--------+--------------------------------+------+-----+---------+----------------+
| Field  | Type                           | Null | Key | Default | Extra          |
+--------+--------------------------------+------+-----+---------+----------------+
| id     | int(11)                        | NO   | PRI | NULL    | auto_increment |
| name   | char(8)                        | YES  |     | NULL    |                |
| gender | enum('male','female','others') | YES  |     | NULL    |                |
| dep_id | int(11)                        | YES  | MUL | NULL    |                |
+--------+--------------------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
# 插入数据
insert into dep(dep_name,dep_desc) values('技术部','修电脑的'),('财务部','收钱的'),('人事部','裁员的');

insert into users(name,gender,dep_id) values('xx','male',1),('yy','male',1),('zz','male',2),('vv','male',3),('ee','male',3),('jj','female',1);

# 报错(插入数据dep_id在dep里不存在报错)
insert into users(name,gender,dep_id) values('kk','female',4);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`text02`.`users`, CONSTRAINT `users_ibfk_1` FOREIGN KEY (`dep_id`) REFERENCES `dep` (`id`))


# 修改dep表里面的id字段
update dep set id=200 where id=2;  #不行
# 删除dep表里面的数据
delete from dep;

# 1 先删除部门对应的员工数据 之后再删除部门
	操作太繁琐

# 2 真正做到数据直接有关系
	更新就同步更新
	删除就同步删除

"""
级联更新  >>>  同步更新
级联删除  >>>  同步删除
"""
create table dep(
id int primary key auto_increment,
dep_name char(8),
dep_desc char(8)
);

create table users(
id int primary key auto_increment,
name char(8),
gender enum('male','female','others'),
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade
on delete cascade
);

# 更新部门数据,员工也跟着更新
update dep set id=200 where id=3;

select * fromm dep;
+-----+-----------+-----------+
| id  | dep_name  | dep_desc  |
+-----+-----------+-----------+
|   1 | 技术部    | 撸码的    |
|   2 | 财务部    | 收钱的    |
| 200 | 人事部    | 裁员的    |
+-----+-----------+-----------+

select * from user;
+----+------+--------+--------+
| id | name | gender | dep_id |
+----+------+--------+--------+
|  1 | xx   | male   |      1 |
|  2 | yy   | male   |      1 |
|  3 | zz   | male   |      2 |
|  4 | vv   | male   |    200 |
|  5 | ee   | male   |    200 |
|  6 | jj   | female |      1 |
+----+------+--------+--------+


# 删除部门表数据 该部门下员工也被删除
delete from dep where id = 200;
Query OK, 1 row affected (0.00 sec)

select * from dep;
+----+-----------+-----------+
| id | dep_name  | dep_desc  |
+----+-----------+-----------+
|  1 | 技术部    | 撸码的    |
|  2 | 财务部    | 收钱的    |
+----+-----------+-----------+
2 rows in set (0.00 sec)

select * from user;
+----+------+--------+--------+
| id | name | gender | dep_id |
+----+------+--------+--------+
|  1 | xx   | male   |      1 |
|  2 | yy   | male   |      1 |
|  3 | zz   | male   |      2 |
|  6 | jj   | female |      1 |
+----+------+--------+--------+
4 rows in set (0.00 sec)
多对多关系
"""
图书表和作者表
"""
create table book(
id int primary key auto_increment,
title vachar(32),
price int,
author_id int,
foreign key(author_id) references book(id)
on update cascade
on delete cascade
);

create author(
id int primary key auto_increment,
name varchar(32),
age int,
book_id int,
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);

"""
按照上述的方式创建 一个都不能创建成功
其实我们只想记录书籍和作者的关系
针对多对多字段表关系  不能在两张原有的表中创建外键
需要单独在开设一张表 专门用来存储两张表数据之间的关系
"""
create table book(
id int primary key auto_increment,
title varchar(32),
price int
);

create table author(
id int primary key auto_increment,
name varchar(32),
age int
);

  create table book2author(
  id int primary key auto_increment,
  author_id int,
  book_id int,
  foreign key(author_id) references author(id)
  on update cascade
  on delete cascade,
  foreign key(book_id) references book(id)
  on update cascade
  on delete cascade
  );

desc book2author;
+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| id        | int(11) | NO   | PRI | NULL    | auto_increment |
| author_id | int(11) | YES  | MUL | NULL    |                |
| book_id   | int(11) | YES  | MUL | NULL    |                |
+-----------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
一对一关系
"""
id name age addr phone habby email……
如果一个表的字段特别多 每次查询又不是所有的字段都能用得到

将表一分为二
    用户表
        用户表
          id name age
        用户详情表
          id addr phone hobby email……
    站在用户表
        一个用户能否对应多个用户详情        不能
    站在详情表
        一个用户详情是否属于多个用户         不能
    结论: 单向的一对多都不成立 那么这个时候两者之间的表关系就是一对一 或者没有关系
"""
一对一  外键字段建在任意一方都可以  但是推荐建在查询频率比较高的表中
create table authordetail(
id int primary key auto_increment,
phone bigint,
addr varchar(64)
);

create table author(
id int primary key auto_increment,
name varchar(32),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail(id)
on update cascade
on delete cascade
);

insert into authordetail(phone,addr) values(13164151001,'湖北武汉'),(13164654135,'湖北武汉');

insert into author(name,age,authordateil_id) values('fx',18,1);

insert into author(name,age,authordateil_id) values('xx',18,1);  # 报错

insert into author(name,age,authordateil_id) values('xx',18,2);

11 查询表SQL

前期准备
create table emp(
  id int not null unique auto_increment,
  name varchar(20) not null,
  sex enum('male','female') not null default 'male', #大部分是男的
  age int(3) unsigned not null default 28,
  hire_date date not null,
  post varchar(50),
  post_comment varchar(100),
  salary double(15,2),
  office int, #一个部门一个屋子
  depart_id int
);

#插入记录
#三个部门:教学,销售,运营
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('jason','male',18,'20170301','张江第一帅形象代言',7300.33,401,1), #以下是教学部
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);


# 当表字段特别多 展示的时候错乱 可以用\G 分行展示
select * from emp\G
sql关键字执行顺序
from
where
select
where筛选条件
# 作用:是对整体数据的一个筛选操作
# 1.查询id大于等于3小于等于6的数据
select * from emp where id >=3 and id <=6;
select * from emp where id between 3 and 6;

# 2.查询薪资是20000或者18000或者17000的数据
select * from emp where salary = 20000 or salary = 18000 or salary = 17000;
select * from emp where salary in (20000,18000,17000);

# 3.查询员工姓名中包含字母o的员工的姓名和薪资
模糊匹配
	like
		% 匹配任意多个字符
		% 匹配任意单个字符
select * from emp where name like '%o%';

# 4.查询员工姓名是由四个字符组成的 姓名和薪资  char_length()   _
select name,salary from emp where name like '____';
select name,salary from emp where char_length(name) = 4;

# 5.查询id小于3或者id大于6的数据
select * from emp where id between 3 and 6;

# 6.查询薪资不在20000,18000,17000范围的数据
select * from emp where salary not in (20000,18000,17000);

# 7.查询岗位描述为空的员工姓名和岗位名  针对null不用等号 用is
select name,post from emp where post_comment is null;

group by分组
什么时候需要分组啊???
	关键字 
		每个 平均 最高 最低 
	聚合函数
	max   最大
	min    最小
	sum   求和
	count  统计值的数目
	avg   平均

# 1.获取每个部门的最高薪资
select post,max(salary) from emp group by post;
select post as '部门',max(salary) as '最高薪资' from emp group by post;

# 2.获取每个部门的最低薪资
select post,min(salary) from emp group by post;
select post as '部门',min(salary) as '最低薪资' from emp group by post;

# 3.获取每个部门的平均薪资
select post,avg(salary) from emp group by post;

# 4.获取每个部门的工资总和
select post,sum(salary) from emp group by post;

# 5.获取每个部门的人数
select post,count(id) from emp group by post;  # 常用 符合逻辑
select post,count(salary) from emp group by post;
select post,count(age) from emp group by post;
select post,count(post_comment) from emp group by post;  # null 不行

# 6.查询分组之后的部门名称和每个部门下所有的员工姓名 
# group_concat 不单单可以支持你获取的分组之后的其他字段,还支持拼接
select post,group_concat(name) from emp group by post;
select post,group_concat(name,'SB') from emp group by post;
select post,group_concat(name,':',salary) from emp group by post;

# concat 不分组的时候用
select concat('NAME:',name) from emp;
# concat_ws:如果多个字段之间的连接符号是相同的情况下 你可以直接使用concat_ws来完成 
select concat_ws(':',name,age,salary) from emp;

# 补充 as语法不单单可以给字段起别名 还可以给表临时起别名
select emp.id,emp.name from emp;
select emp.id,emp.name from emp as t1; # 报错
select t1.id,t1.name from emp as t1;

# 7.查询每个人的年薪  12薪
select name,salary*12 from emp;

分组注意事项
# 关键字where 和group by 同时出现的时候group by 必须在where后面
where先对整体数据进行过滤之后再分组
where筛选条件不能使用聚合函数

# 统计各部门年龄在30岁以上的员工平均薪资
select post,avg(salary) from emp where age > 30 group by post;
having分组之后的筛选条件
having的语法和where是一致的
只不过having是在分组之后进行的过滤操作
即having是可以直接使用聚合函数的

# 统计各部门年龄在30岁以上的员工平均工资并且保留平均薪资大于10000的部门
select post,avg(salary) from emp where age >30 group by post having avg(salary) >10000;
distinct去重
""
一定要注意 必须是完全一样的数据才可以去重
一定不要把主键忽视了 有主键存在的情况下 是不可能去重的
""

select distinct age from emp;
order by 排序
select * from emp order by salary;
select * from emp order by salary asc; 
select * from emp order by salary desc;
""
order by 默认是升序  asc   asc可以省略不写
也可以修改为降序 desc
""
# 先按照age降序排  如果碰到age相同 则再按照salary升序排序
select * from emp order by age desc,salary asc;

# 统计各部门年龄在10岁以上的员工平均工资并且保留平均薪资大于1000的部门,然后对平均工资降序排序
select post,avg(salary) from emp where age >10 group by post having avg(salary) >1000 order by avg(salary) desc;
limit限制展示条数
select * from emp;
select * from emp limit 3;  # 只展示3条数据
select * from emp limit 0,5;
select * from emp limit 5,5;
第一个参数是起始位置,第二个参数是展示条数
正则
 select * from emp where name regexp '^j.*(n|y)$';

12 多表操作

建表

create table dep(
id int,
name varchar(20) 
);

create table emp(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);

#插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营');

insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);
表查询
select * from dep,emp; # 结果 笛卡尔积

select * from dep,emp where emp.dep_id = dep.id;

拼表操作方法:
    inner join   内连接
    left join     左连接
    right join   右连接
    union        全连接

# inner join 内连接 只能拼接两张表公有的数据部分
select * from emp inner join dep on emp.dep_id = dep.id;

# left join 左连接  左表所有的数据都展示出来  没有对应的项用NULL
select * form emp left join dep on emp.dep_id = dep.id;

# right join 右连接 右表所有数据都展示出来 没有对应的项 不显示
select * from emp right join dep on emp.dep_id = dep.id;

# union全连接 左右两表所有的数据都展示出来
select * from emp left join dep on emp.dep_id = dep.id 
union
select * from emp right join dep on emp.dep_id = dep.id ;
子查询
"""
子查询就是我们平时解决问题的思路
	分步骤解决问题
		第一步
		第二部
		……
将一个查询语句的结果当做另外一个查询语句的条件使用
"""
# 查询部门是技术或者人力资源的员工信息
# 第一步获取部门id
select id from dep where name in ('技术','人力资源');
# 第二步 通过获取的部门id 查询对应的员工
select * from emp where dep_id in (200,201);

# 合并
select * from emp where dep_id in (select id from dep where name in ('技术','人力资源'));

关键字exists
"""
	只返回布尔值 True False
    返回True的时候外层查询语句执行
    返回False的时候外层查询语句不再执行
"""
select * from emp where exists 
    (select id from dep where id>3);
select * from emp where exists 
    (select id from dep where id>300);
多表查询综合
# 查询平均年龄在25岁以上的部门名称
# 表连接方式
select dep.name from emp inner join dep on emp.dep_id = dep.id group by dep.name having avg(age) >25;
# 子查询
select name from dep where id in (select dep_id from emp group by dep_id having avg(age)>25);

返回顶部

 

posted @ 2022-03-30 15:32  XingFang  阅读(36)  评论(0编辑  收藏  举报