Mysql关联查询

目录

一、分组与限制

1.分组过滤

2.结果限制

3.编写数据

二、子查询

1.单行单列

2.多行单列

3.多行多列

三、关联查询

1.合并查询

2.表连接查询

四、DML操作

1.添加

2.删除

五、数据表操作

1.数据类型

2.创建表

3.数据表操作

六、约束

1.实体完整性约束

2.域完整性约束

3.外键约束

七、事务

1.概述

2.事务的边界

3.原理

4.事务特性

1.应用

八、权限管理

九、视图

1.概述

2.应用

十、SQL分类与综合练习

1.SQL语言分类

2.综合案例



一、分组与限制

1.分组过滤

语法select 字段 from 表 where 条件 group by 字段 having 条件

分组过滤having和where类似,都是用于条件判断;

区别在于:where是最核心的条件判断; 但having只能用在分组的条件判断

#分组过滤:
#统计60、70、90号部门的最高工资
#思路:
#1).	确定分组依据(department_id)
select department_id from t_employees group by department_id;
#2).	对分组后的数据,过滤出部门编号是60、70、90信息
select department_id from t_employees group by department_id having department_id in(60,70,90);
#3).	max()函数处理
select department_id,max(salary) from t_employees group by department_id having department_id in(60,70,90);

2.结果限制

#限定查询  限定查询出来的条数  SELECT 列名 FROM 表名 [LIMIT 起始行,查询行数]()
#应用场景:分页查询
#查询表中前五名员工的所有信息
select * from t_employees limit 0,5;

#查询表中从第四条开始,查询 10 行
select * from t_employees limit 3,10;

#分页: 每页5条   第1页:0,5   第2页:5,5  第3页:10,5
#算法: 起始行=(当前页-1)*每页条数

3.编写数据

select 字段 from 表 where 条件 group by 字段 having 条件 order by 字段 limit 起始行,条数

二、子查询

概述:会出现两个查询语句;一个查询的结果,是另一个查询的条件;这个结果就是子查询

1.单行单列

子查询的结果为单行单例;是最基本,也是最常用的一种子查询

#子查询--单行单列
#查询工资大于Bruce 的员工信息
#1.先查询到 Bruce 的工资(一行一列)
select salary from t_employees where FIRST_NAME='Bruce';  #子查询
#2.查询工资大于 Bruce 的员工信息
select * from t_employees where salary>6000;
#3.组合
select * from t_employees where salary>(select salary from t_employees where FIRST_NAME='Bruce');

2.多行单列

子查询的结果是多行单列的应用,往往有两种情况:1.枚举查询 2. all| any关键字

#枚举的多行单列:   where 字段 in(值1,值2..)
#查询与名为'King'同一部门的员工信息
#思路:
#1.	先查询 'King' 所在的部门编号(多行单列)
select department_id from t_employees where LAST_NAME='King';
#2.	再查询80、90号部门的员工信息
select * from t_employees where department_id in(80,90);
#3.组合
select * from t_employees where department_id in(select department_id from t_employees where LAST_NAME='King');


#any|all的使用  any-匹配部分   all-匹配所有
#工资高于60部门所有人的信息   
#1.查询 60 部门所有人的工资(多行单列)
select salary from t_employees where DEPARTMENT_ID=60;
#2.查询高于 60 部门所有人的工资的员工信息(高于所有-高于最高的)
select * from t_employees where salary > ALL(select salary from t_employees where DEPARTMENT_ID=60);
#。查询高于 60 部门的工资的员工信息(高于部分-高于最低的)
select * from t_employees where salary > ANY(select salary from t_employees where DEPARTMENT_ID=60);

3.多行多列

子查询的结果是一张虚拟表,继续当成表来使用即可

SELECT 列名 FROM(子查询的结果集)WHERE 条件;

#多行多列的子查询
#查询员工表中工资排名前 5 名的员工信息
#思路:
#1.	先对所有员工的薪资进行排序(排序后的临时表)
select * from t_employees order by salary desc;
#2.	再查询临时表中前5行员工信息
select * from (select * from t_employees order by salary desc) temp limit 0,5;

#简化写法:
select * from t_employees order by salary desc limit 0,5;

三、关联查询

1.合并查询

合并查询,需要合并多张表;在平时应用中不常用;合并的表字段数量要一致,否则会有问题

应用场景:多张表结构一致,并进行汇总才用到; 例如:多个班级学生信息汇总

#创建t1表和t2表
#合并查询
#合并两张表的结果,去除重复记录
select * from t1 UNION select * from t2;

#合并两张表的结果,不去除重复记录(显示所有)
select * from t1 UNION ALL select * from t2;

2.表连接查询

表连接查询分为:内连接和外连接

内连接:两张表中能够匹配上的记录则显示出来;匹配不上的,则不显示

外连接分为左外和右外:

左外:以左表为标准,所有记录都会显示;如果右表记录匹配不上则显示为null

右外:以右表为标准,所有记录都会显示;如果左表记录匹配不上则显示为null

#创建teacher表和couse表
#内连接:
select * from teacher t,couse c where t.id=c.t_id;       #MySQL专用
select * from teacher t INNER JOIN couse c ON t.id=c.t_id;   #统一标准

#左外连接
select * from teacher t LEFT JOIN couse c ON t.id=c.t_id;   

#右外连接
select * from teacher t right JOIN couse c ON t.id=c.t_id; 

#三表关联案例:
#查询所有员工工号、名字、部门名称、部门所在国家ID
#员工工号、名字-员工表; 部门名称-部门表  国家ID-地区表
select e.employee_id,e.first_name,d.DEPARTMENT_NAME,l.COUNTRY_ID from t_employees e 
INNER JOIN t_departments d ON e.DEPARTMENT_ID=d.DEPARTMENT_ID 
INNER JOIN t_locations l ON d.LOCATION_ID=l.LOCATION_ID;

四、DML操作

DML是数据操作语言,针对表中的增删改的操作; 查询则叫做DQL

1.添加

语法1:insert into 表名(字段1,字段2..) values(值1,值2...) ---常用

语法2:insert into 表名 values(值1,值2...) 必须和表字段一一对应,且全部字段要添加数据(如果id为主键自增可以设置null填入)

#添加一条工作岗位信息
insert into t_jobs(job_id,job_title,min_salary,max_salary) values('AD_IT','IT_PRO',10000,20000);  #推荐
insert into t_jobs values('AD_XS','XSY',5000,15000);  #注意:字段必须按顺序,且写全

2.删除

语法: delete from 表 where 条件

注意:必须要加where,否则删除表的所有记录

#删除编号为135 的员工
delete from t_employees where employee_id=135;

#删除姓Peter,并且名为 Hall 的员工
delete from t_employees where first_name='Peter' and last_name='Hall';

#清除数据表
TRUNCATE table teacher;  #类似delete from teacher  区别:TRUNCATE 删除表再重新创建

五、数据表操作

1.数据类型

建表前,需要先弄清除数据库的数据类型分类,可以分为:数值类型,日期类型,字符串类型

这些类型重点记住:int,double(M,D), date,datetime,varchar(长度)

2.创建表

建表前,需要先弄清除数据库的数据类型分类,可以分为:数值类型,日期类型,字符串类型

这些类型重点记住:int,double(M,D), date,datetime,varchar(长度)

3.数据表操作

#表字段的操作:    ALTER TABLE 表名 操作;
#在课程表基础上添加gradeId 列
alter table sub add gradeId int;

#修改课程表中课程名称长度为10个字符
alter table sub MODIFY name varchar(10);

#删除课程表中 gradeId 列
alter table sub drop gradeId;

#修改课程表中 hour 列为 h
alter table sub change hour h int;

#修改课程表的sub 为 subs
alter table sub rename subs;

#删除subs表
drop table subs;

六、约束

问题:在往已创建表中新增数据时,可不可以新增两行相同列值得数据?]()

如果可行,会有什么弊端?

答:可以创建;弊端:无法识别唯一的一条记录; 造成数据的读写肯定会出问题; 需要进行约束

1.实体完整性约束

一条记录代表着一个实体对象,也是就每条记录都需要唯一性约束

  1. 主键约束

    表中每条记录的唯一标识,不代表业务逻辑; 注意:主键不能为null

  2. 唯一约束

    主键约束就是唯一约束,区别在于唯一约束设置到除id以外的字段;且允许为null

  3. 主键自增长

    主键自增长,默认从1开始,每次添加都+1;添加数据更方便

#主键约束:
create table sub(
	id int primary key auto_increment,  #主键约束,不能为null   自增长
  name varchar(20) UNIQUE,  #唯一约束
  hour int 
)
select * from sub;
insert into sub(name,hour) values('java',60);
insert into sub(name,hour) values('h5',55);

2.域完整性约束

域完整性约束是针对字段中的单元格的值的范围的限制

create table sub(
	id int primary key auto_increment,  
  name varchar(20) UNIQUE not null,  #非空约束
  hour int default 30   #默认值为30
)
select * from sub;
insert into sub(name) values('java');
insert into sub(name,hour) values('h5',55);

3.外键约束

两张表中的单元格的值的范围限制; 这两张表一张作为主表,一张作为从表

主表:关联字段的主键所在表为主表;关联字段的非主键所在表则是从表

外键约束规则:(注意:外键约束需要设置到从表中)

创建时,先创建主表;添加数据时,先添加主表数据

删除时,先删除从表或数据;再删除主表或数据

#外键约束
drop table teacher;  #主表
drop table course;   #从表

#先创建主表   创建时先创建主表及添加数据
create table teacher(
	 id int primary key auto_increment,
   name varchar(20)
);
insert into teacher(name) values('凤姐');
insert into teacher(name) values('芙蓉');
select * from teacher;

#再创建从表,并设置外键约束
create table course(
	 id int primary key auto_increment,
   name varchar(30),
   t_id int,  #外键  从表中的关联字段是外键
   #CONSTRAINT 标记名  FOREIGN KEY(外键名) REFERENCES 主表(主键)
   CONSTRAINT fk FOREIGN KEY(t_id) REFERENCES teacher(id)   #外键约束
);
select * from course;
insert into course(name,t_id) values('h5',1);  #添加时t_id只能时主键中存在的1或2的主键值

#删除时,先删从表或数据,再删主表或数据

七、事务

1.概述

事务是原子性操作(不可分割的整体);处在事务中的多个SQL语句,要么都成功,则提交;要么都失败,则回滚

2.事务的边界

事务的边界,就是事务开启或结束的过程

开始: 启动事务 start transaction; 开启事务后,则进入事务中;中间可执行SQL语句

执行多条SQL语句

结束:(提交或回滚)

提交:多条SQL语句都执行成功,则提交; commit;

回滚:如果有任意SQL语句失败,则回滚,回滚到未发生的状态; rollback;

3.原理

开启事务后,相当于开辟了缓冲区(回滚段);所有SQL指令的执行都是在缓冲区中进行;如果都成功了,则执行提交,意味着提交到数据库中永久写入;如果有失败的,则执行回滚(清除缓冲区)

4.事务特性

事务特性:ACID; 原子性,一致性,隔离性,持久性

原子性:事务操作要么都成功,要么都失败

一致性:事务的成功或失败,最终完成的状态是一致的(例如,转账的总和不变)

隔离性:处在事务中,与外界的操作是完全隔离的;除非进行了提交或回滚

持久性:进行了提交,则永久性写到了数据库中

1.应用

#事务的操作   ---模拟转账功能
#zs和ls都有1000块;zs转200给ls
create table account(
	 id int primary key auto_increment,
   name varchar(20),
   money int
)
insert into account(name,money) values('zs',1000);
insert into account(name,money) values('ls',1000);
select * from account;

start TRANSACTION;  #开启事务

update account set money=money-200 where name='zs';

#中途出现异常,则会跳到回滚语句

update account set money=money+200 where name='ls';

commit;  #上述的SQL操作无异常,则进入提交

rollback;  #如果有一条语句出现异常,则会跳到回滚

八、权限管理

创建一个用户,并指定好操作权限(增删改查权限)

#权限管理
#创建用户
create user 'zs' IDENTIFIED by '123';

#给用户分配权限
GRANT ALL ON mydb1.* to 'zs'; 

#撤销用户权限
REVOKE ALL ON mydb1.* from 'zs';

#删除用户 zs
drop user 'zs';

九、视图

1.概述

视图就是一张虚拟表;从原表中抽取出来的虚拟表; 关于虚拟表的操作,也会联动的改变原表

好处:

1.屏蔽了原表的重要数据,提升安全性

2.当需要从多表中提取数据时,使用视图可以提升性能

缺点:

1.单表的操作,会变得复杂(增删改的操作要联动原表)

2.复杂的视图是无法被修改的 例如:聚合函数形成的视图

2.应用

#视图操作:
#创建视图 创建 t_emp 的视图,其视图从 t_employees 表中查询到员工编号、员工姓名、员工邮箱、工资
create view t_emp as select employee_id,first_name,email,salary from t_employees;

#视图的操作,与原表一致的;且会联动改变原表
select * from t_emp;
select * from t_employees;

update t_emp set salary=30000 where employee_id=100;

#修改视图
#方式1:创建或替换视图   存在则替换,不存在则创建
create or REPLACE view t_emp as select employee_id,salary from t_employees;

#方式 2:直接对已存在的视图进行修改
alter view t_emp as select employee_id,first_name,email,salary from t_employees;

#删除t_emp视图
drop view t_emp;

#视图的注意事项:如果视图是聚合函数或分组形成的,则不能变更
create  view emp as select count(*) as count from t_employees;
select * from emp;
update emp set count=5;

十、SQL分类与综合练习

1.SQL语言分类

  • 数据查询语言DQL(Data Query Language):select、where、order by、group by、having 。

  • 数据定义语言DDL(Data Definition Language):create、alter、drop。

  • 数据操作语言DML(Data Manipulation Language):insert、update、delete 。

  • 事务处理语言TPL(Transaction Process Language):commit、rollback 。

  • 数据控制语言DCL(Data Control Language):grant、revoke。

2.综合案例

#查询所有用户的订单
select * from user u INNER JOIN orders o ON u.userId=o.userId;

#查询用户id为 1 的所有订单详情
select * from user u INNER JOIN orders o ON u.userId=o.userId
inner JOIN orderitem oi ON o.oid=oi.oid and u.userId=1;

#查看用户为张三的订单
#先查用户张三的userid
select userId from user where username='张三';
#再匹配userID为1的订单
select * from orders where userId = (select userId from user where username='张三');


#查询出订单的价格大于800的所有用户信息。
#先查询订单大于800的userId
select DISTINCT userId from orders where totalprice>800;
#再使用枚举查询
select * from user where userId in (select DISTINCT userId from orders where totalprice>800);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值