内连接
隐式内连接
看不到Join关键字,条件使用where指定
语法:select 列名,列名...from 表名1,表名2where 表名1.列名=表名2.列名
select *from fruit ,price where fruit.price_id=price.id;
说明:在产生两张表的笛卡尔积的数据后,通过条件删选出正确的结果。
显示内连接
使用 inner join...on语句,可以省略inner
语法:select *from 表名1 inner join 表名2 on 条件;
或者 select * from 表名1 join 表名2 on 条件
具体操作
select *from fruit inner join price on fruit.price_id=price.id
小结
1.隐式连接看不到join,显示连接看到join
2.内连接查询步骤:
1.确定查询几张表
2.确定表连接哪些条件
3.根据需要在操作
左外连接
左外连接可以理解为:用左边表去右边表中查询对应记录,不管是否找到,都将显示左边表中全部记录
左外连接: 使用 left outer join...on,outer 可以省略
select *from 表1 left outer join 表2 on 条件;
用 left 关键字之前的表,是定义为左侧。left 关键字之后的表,定义右侧。
查询的内容:以左侧的表为主,如果左侧有数据,右侧没有对应的数据,仍然会把左侧数据进行显示。
select *from fruit left outer join price on fruit.price_id=price.id
右外连接
用右边表去左边表查询记录,不管是否找到,右边表的记录都将显示。
右外连接:使用 right outer join...on,outer 可以省略
语法:select *from 表1 right outer join 表2 on 条件;
select *from fruit outer join price on fruit.price_id=price.id
子查询
什么是子查询
一条查询语句结果作为另一条查询语法一部分
select 查询字段 from 表 where 条件;
举例: select * from employee where salary =(select max(salary)from employee);
子查询的三种情况
单行单列 多行单列 多行多列
单行单列
1.查询最高工资是多少
select max(salary)from emp;
根据最高工资到员工表查询到对应的员工信息
select *from emp where salary =(select max(salary)from emp);
到员工表查询小于平均的员工信息
select *from emp where salary <(select avg(salary)from emp);
子查询结果是单行单列时父查询如何处理?
select 查询字段 from 表where 字段=(子查询);
通常作为父查询条件
子查询是多行单列的时候
子查询的结果是多行单列,结果集类似一个数组,在where后面作为条件,父查询使用in运算符
select 查询字段 from 表 where 字段 in(子查询);
查询工资大于5000的员工,来自于哪些部门的名字
先查询大于5000的员工所在的部门id
select dept_id from emp where salary >5000;
在查询在这些部门id中部门的名字
select dept.name from dept where dept.id in(select dept_id from emp where salary >5000);
子查询的结果是多行单列时父查询如何处理?
放在父查询的条件位置,使用in
子查询的结果是多行多列
子查询的结果是多行多列,在from后面作为表
select 查询字段from (子查询)表别名 where条件;
注意:子查询作为表需要取别名,否则这张表没用名称无法访问表中的字段
查询出2011年以后入职的员工信息,包括部门名称
在员工表中查询2011-1-1以后入职的员工
select *from empty where join date >"2011-1-1"
查询所有的部门信息,与上面的虚拟表中的信息组合,找出所有部门id等于dept_id
select *from dept d,(select *from emp where join_date >"2011-1-1") e where e.dept_id=d.id;
小结
三种子查询情况:单行单列,多行单列,多行多列
单行单列:作为父查询的条件
多行单列:作为父查询的条件,通常使用in
多行多列:作为父查询的一张表(虚拟表)
事务的概念
mysql中可以有两种方式进行事务操作
1.手动提交事务:先开启,再提交
2.自动提交事务(默认的):即执行一条SQL语句提交一次事务。
事务有关的SQL语句:
SQL语句 描述
start transaction; 开启手动控制事务
commit; 提交事务
rollback; 回滚事务
手动提交事务的步骤
第一种情况:开启事务——>执行SQL语句——>成功——>提交事务
第二种情况:开启事务——>执行SQL语句——>失败——>回滚事务
在mysql中,mysql默认是自动提交事务,就是执行一个sql语句就会提交一次事务。
-- 查看mysql是否是自动提交事务
show variables like'%commit%'
-- autocommit 值是on表示开启了自动提交事务,如果值是off表示关闭自动提交事务
-- a - 100
update account set money = money - 100where name='a';
-- b + 100
update account set money = money + 100where name='b';
-- 关闭自动提交事务
-- autocommit 值是on表示开启了自动提交事务,如果值是off表示关闭自动提交事务
-- 可以给其设置值 1 表示on 0 表示off
set autocommit = 0
-- 手动控制事务
start transaction;
-- 执行转账的sql语句都位于都一个事务中,要么都成功,要么都失败--
-- a - 100
update account set money = money - 100where name='a';
-- b + 100
update account set money = money + 100where name='b';
-- 一切正常,提交事务永久性改变
commit;
-- 小结:
-- 1.在start transaction开启事务之前会将之前没有提交事务的数据先提交然后在控制事务
-- 2.在mysql中关闭自动提交事务只是临时的,如果重新启动mysql服务或者重新连接mysql服务器那么又会
-- 开启自动提交事务
事务的特性
原子性:一组sql语句不能被拆分,要么都成功,要么都失败
一致性:操作事务前后数据是一致的。
原来:
A:100
B:100
转账之后:
A:90
B:110
持久性:事务被提交之后,数据就会永久性保存。
隔离性:多个事务之间没有关系。
事务1:a给b转账
事务2:c给d转账
事务并发访问引发的问题
前提:不考虑隔离性。
有三个问题:
1)脏读:最严重的,一定避免
2)不可重复读
3)幻读或者虚读
小结:
脏读:未提交事务 数据内容
不可重复读:已经提交事务 数据内容 update
幻读:已经提交事务 行记录数 insert delete