MySql多表查询 事务及DCL

目录
  • 一、多表查询
    • 1、查询语法
    • 2、 准备sql
    • 3、 笛卡尔积
    • 4、多表查询的分类
      • 4.1 内连接查询
      • 4.2 外链接查询
      • 4.3 子查询
    • 4.4 子查询不同情况
    • 5、多表查询练习
    • 二、事务
      • 1. 事务的基本介绍
      • 2. 操作
      • 2、MySQL数据库中事务默认自动提交
      • 3. 事务的四大特征

一、多表查询

1、查询语法

select
  列名列表
 from
  表名列表
 where....

2、 准备sql

 # 创建部门表
 CREATE TABLE dept(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(20)
 );
 INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');
 # 创建员工表
 CREATE TABLE emp (
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10),
  gender CHAR(1), -- 性别
  salary DOUBLE, -- 工资
  join_date DATE, -- 入职日期
  dept_id INT,
  FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键)
 );
 INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);
 INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);
 INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);
 INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);
 INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);

3、 笛卡尔积

  • 有两个集合A,B .取这两个集合的所有组成情况。
  • 要完成多表查询,需要消除无用的数据

4、多表查询的分类

4.1 内连接查询

隐式内连接:使用where条件消除无用数据

例子

-- 查询所有员工信息和对应的部门信息
SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
-- 查询员工表的名称,性别。部门表的名称
SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;

SELECT
t1.name, -- 员工表的姓名
t1.gender,-- 员工表的性别
t2.name -- 部门表的名称
FROM
 emp t1,
 dept t2
WHERE
t1.`dept_id` = t2.`id`;

显式内连接:

 语法:

select 字段列表 from 表名1 [inner] join 表名2 on 条件

例如:

* SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;
* SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;

4.2 外链接查询

4.2.1 左外连接
  • * 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;
  • * 查询的是左表所有数据以及其交集部分。

 例子:

-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称
SELECT  t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;
4.2.2右外连接

语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
 查询的是右表所有数据以及其交集部分。

 例子:

SELECT  * FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;

4.3 子查询

概念:查询中嵌套查询,称嵌套查询为子查询。
-- 查询工资最高的员工信息
-- 1 查询最高的工资是多少 9000

SELECT MAX(salary) FROM emp;

-- 2 查询员工信息,并且工资等于9000的

SELECT * FROM emp WHERE emp.`salary` = 9000;

-- 一条sql就完成这个操作。子查询

SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);

4.4 子查询不同情况

子查询的结果是单行单列的:

子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =

-- 查询员工工资小于平均工资的人

SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);

子查询的结果是多行单列的:

子查询可以作为条件,使用运算符in来判断
-- 查询'财务部'和'市场部'所有的员工信息

SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';
SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;
-- 子查询
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');

子查询的结果是多行多列的:

子查询可以作为一张虚拟表参与查询
 -- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
 -- 子查询

SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2
WHERE t1.id = t2.dept_id;

-- 普通内连接

SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'

5、多表查询练习

   -- 部门表
   CREATE TABLE dept (
     id INT PRIMARY KEY PRIMARY KEY, -- 部门id
     dname VARCHAR(50), -- 部门名称
     loc VARCHAR(50) -- 部门所在地
   );

   -- 添加4个部门
   INSERT INTO dept(id,dname,loc) VALUES
   (10,'教研部','北京'),
   (20,'学工部','上海'),
   (30,'销售部','广州'),
   (40,'财务部','深圳');
   -- 职务表,职务名称,职务描述
   CREATE TABLE job (
     id INT PRIMARY KEY,
     jname VARCHAR(20),
     description VARCHAR(50)
   );

   -- 添加4个职务
   INSERT INTO job (id, jname, description) VALUES
   (1, '董事长', '管理整个公司,接单'),
   (2, '经理', '管理部门员工'),
   (3, '销售员', '向客人推销产品'),
   (4, '文员', '使用办公软件');
   -- 员工表
   CREATE TABLE emp (
     id INT PRIMARY KEY, -- 员工id
     ename VARCHAR(50), -- 员工姓名
     job_id INT, -- 职务id
     mgr INT , -- 上级领导
     joindate DATE, -- 入职日期
     salary DECIMAL(7,2), -- 工资
     bonus DECIMAL(7,2), -- 奖金
     dept_id INT, -- 所在部门编号
     CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
     CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
   );

   -- 添加员工
   INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
   (1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
   (1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
   (1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
   (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
   (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
   (1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
   (1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
   (1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
   (1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
   (1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
   (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
   (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
   (1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
   (1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
   -- 工资等级表
   CREATE TABLE salarygrade (
     grade INT PRIMARY KEY,   -- 级别
     losalary INT,  -- 最低工资
     hisalary INT -- 最高工资
   );

   -- 添加5个工资等级
   INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
   (1,7000,12000),
   (2,12010,14000),
   (3,14010,20000),
   (4,20010,30000),
   (5,30010,99990);

需求:

-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描
    分析:
     1.员工编号,员工姓名,工资,需要查询emp表  职务名称,职务描述 需要查询job表
     2.查询条件 emp.job_id = job.id

    SELECT
    t1.`id`, -- 员工编号
    t1.`ename`, -- 员工姓名
    t1.`salary`,-- 工资
    t2.`jname`, -- 职务名称
    t2.`description` -- 职务描述
   FROM
    emp t1, job t2
   WHERE
    t1.`job_id` = t2.`id`;

-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
   
    分析:
     1. 员工编号,员工姓名,工资 emp  职务名称,职务描述 job  部门名称,部门位置 dept
     2. 条件: emp.job_id = job.id and emp.dept_id = dept.id

  SELECT
    t1.`id`, -- 员工编号
    t1.`ename`, -- 员工姓名
    t1.`salary`,-- 工资
    t2.`jname`, -- 职务名称
    t2.`description`, -- 职务描述
    t3.`dname`, -- 部门名称
    t3.`loc` -- 部门位置
   FROM
    emp t1, job t2,dept t3
   WHERE
    t1.`job_id` = t2.`id` AND t1.`dept_id` = t3.`id`;

-- 3.查询员工姓名,工资,工资等级
   
    分析:
     1.员工姓名,工资 emp  工资等级 salarygrade
     2.条件 emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalary

emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary

  SELECT
    t1.ename ,
    t1.`salary`,
    t2.*
   FROM emp t1, salarygrade t2
   WHERE t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`;

-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
    分析:
     1. 员工姓名,工资 emp , 职务名称,职务描述 job 部门名称,部门位置,dept  工资等级 salarygrade
     2. 条件: emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary

     SELECT
    t1.`ename`,
    t1.`salary`,
    t2.`jname`,
    t2.`description`,
    t3.`dname`,
    t3.`loc`,
    t4.`grade`
   FROM
    emp t1,job t2,dept t3,salarygrade t4
   WHERE
    t1.`job_id` = t2.`id`
    AND t1.`dept_id` = t3.`id`
    AND t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`;

-- 5.查询出部门编号、部门名称、部门位置、部门人数 
       分析:
     1.部门编号、部门名称、部门位置 dept 表。 部门人数 emp表
     2.使用分组查询。按照emp.dept_id完成分组,查询count(id)
     3.使用子查询将第2步的查询结果和dept表进行关联查询

   SELECT
    t1.`id`,t1.`dname`,t1.`loc` , t2.total
   FROM
    dept t1,
    (SELECT
     dept_id,COUNT(id) total
    FROM
     emp
    GROUP BY dept_id) t2
   WHERE t1.`id` = t2.dept_id;

-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询

分析:
     1.姓名 emp, 直接上级的姓名 emp
      * emp表的id 和 mgr 是自关联
     2.条件 emp.id = emp.mgr
     3.查询左表的所有数据,和 交集数据
      * 使用左外连接查询

   select
    t1.ename,
    t1.mgr,
    t2.`id`,
    t2.ename
   from emp t1, emp t2
   where t1.mgr = t2.`id`;

   SELECT
    t1.ename,
    t1.mgr,
    t2.`id`,
    t2.`ename`
   FROM emp t1
   LEFT JOIN emp t2
   ON t1.`mgr` = t2.`id`;

二、事务

1. 事务的基本介绍

概念:

*  如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。

2. 操作

开启事务: start transaction;
回滚:rollback;
提交:commit;

例子:

  CREATE TABLE account (
   id INT PRIMARY KEY AUTO_INCREMENT,
   NAME VARCHAR(10),
   balance DOUBLE
  );
  -- 添加数据
  INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
​

  SELECT * FROM account;
  UPDATE account SET balance = 1000;
  -- 张三给李四转账 500 元

  -- 0. 开启事务
  START TRANSACTION;
  -- 1. 张三账户 -500

  UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
  -- 2. 李四账户 +500
  -- 出错了...
  UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';

  -- 发现执行没有问题,提交事务
  COMMIT;

  -- 发现出问题了,回滚事务
  ROLLBACK;

2、MySQL数据库中事务默认自动提交

事务提交的两种方式

自动提交:
  mysql就是自动提交的
 一条DML(增删改)语句会自动提交一次事务。
手动提交:
Oracle 数据库默认是手动提交事务
  需要先开启事务,再提交
 修改事务的默认提交方式:
 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交
修改默认提交方式: set @@autocommit = 0;

3. 事务的四大特征

原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
 隔离性:多个事务之间。相互独立。
 一致性:事务操作前后,数据总量不变
 事务的隔离级别(了解)

概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在问题:
   脏读:一个事务,读取到另一个事务中没有提交的数据
不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
  幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
 * 隔离级别:
 read uncommitted:读未提交
   * 产生的问题:脏读、不可重复读、幻读
read committed:读已提交 (Oracle)
   * 产生的问题:不可重复读、幻读
 repeatable read:可重复读 (MySQL默认)
   * 产生的问题:幻读
 serializable:串行化
   * 可以解决所有的问题

(0)

相关推荐

  • MySQL slave 延迟一列 外键检查和自增加锁

    目录 MySQL slave 延迟 外键检查和自增加锁 一.现象 二.pscak 采样 三.自增锁获取逻辑 四.方案 MySQL slave 延迟 外键检查和自增加锁 一.现象 延迟大,大事物. 表结构 无IO SQL THREAD占用CPU 100% 二.pscak 采样 采样30个点 外键检查 占70% 自增锁获取 占30% 三.自增锁获取逻辑 逻辑如下其实也是innodb_autoinc_lock_mode参数的作用 switch (lock_mode) { case AUTOINC_NO

  • 基于jsp+mysql实现在线水果销售商城系统

    目录 研究意义 国内外研究现状.水平和发展趋势 主要功能说明 管理员角色 用户角色 主要技术 首页主要功能 水果分类查看 热门水果 新品水果 我的订单 主要代码实现 个人信息 wen.xml配置 后台管理: 用户管理: 水果管理: 水果类型: 研究意义 日益发展的信息技术,互联网经济的快速兴起,网上的购物日益受到人们的关注,蔬菜水果网上批发市场模式也必然成为其潮流发展一部分. 基于 springboot 技术的水果在线批发系统借助于遍布全球的互联网, 进行水果的市场消费流动,因此水果的批发既可以

  • docker实现mysql主从复制的示例代码

    目录 一.概述 1.原理 2.实现 三.创建Slave实例 四.主从配置 总结: 五.参考 一.概述 1.原理 master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中: slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件 同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启

  • Mysql ALTER TABLE加字段的时候到底锁不锁表

    目录 Mysql5.6版本之前 Mysql5.6版本之后 总结 注意 Mysql5.6版本之前 更新步骤 对原始表加写锁 按照原始表和执行语句的定义,重新定义一个空的临时表. 对临时表进行添加索引(如果有). 再将原始表中的数据逐条Copy到临时表中. 当原始表中的所有记录都被Copy临时表后,将原始表进行删除.再将临时表命名为原始表表名. 这样的话整个DDL过程的就是全程锁表的. Mysql5.6版本之后 更新步骤 对原始表加写锁 按照原始表和执行语句的定义,重新定义一个空的临时表.并申请ro

  • MySQL数据库 Load Data 多种用法

    目录 MySQL Load Data 的多种用法 一.LOAD 基本背景 二.LOAD 基础参数 三.LOAD 示例数据及示例表结构 四.LOAD 场景示例 五.LOAD 总结 MySQL Load Data 的多种用法 一.LOAD 基本背景 我们在数据库运维过程中难免会涉及到需要对文本数据进行处理,并导入到数据库中,本文整理了一些导入导出时常见的场景进行示例演示. 二.LOAD 基础参数 文章后续示例均使用以下命令导出的 csv 格式样例数据(以 , 逗号做分隔符,以 " 双引号作为界定符)

  • 基于 Mysql 实现一个简易版搜索引擎

    目录 基于 Mysql 实现一个搜索引擎 一.ngram 全文解析器 二.创建全文索引 1.建表时创建全文索引 2.通过 alter table 方式 3.通过 create index 方式 三.检索方式 1.自然语言检索(NATURAL LANGUAGE MODE) 四.与 Like 对比 基于 Mysql 实现一个搜索引擎 前言: 其实 Mysql 很早就支持全文索引了,只不过一直只支持英文的检索,从5.7.6 版本开始,Mysql 就内置了 ngram 全文解析器,用来支持中文.日文.韩

  • VMware workstation16 中Centos7下MySQL8.0安装过程及Navicat远程连接

    目录 一.CentOS7+MySQL8.0,yum源安装 二.登录mysql以及修改密码 三.远程登录 1.MySQL yum源安装 2.安装后,首次登录mysql以及密码配置 3.远程登录问题(Navicat15为例) 一.CentOS7+MySQL8.0,yum源安装 1.安装mysql前应卸载原有mysql,如果没有请忽虑 1.1找出原有mysql安装目录 输入命令 rpm -qa | grep mysql 后出现以下几行 1.2用以下命令依次删除上述出现的文件 1.3删除mysl配置文件

  • MySql多表查询 事务及DCL

    目录 一.多表查询 1.查询语法 2. 准备sql 3. 笛卡尔积 4.多表查询的分类 4.1 内连接查询 4.2 外链接查询 4.3 子查询 4.4 子查询不同情况 5.多表查询练习 二.事务 1. 事务的基本介绍 2. 操作 2.MySQL数据库中事务默认自动提交 3. 事务的四大特征 一.多表查询 1.查询语法 select   列名列表  from   表名列表  where.... 2. 准备sql # 创建部门表 CREATE TABLE dept( id INT PRIMARY K

  • MySQL单表查询常见操作实例总结

    本文实例总结了MySQL单表查询常见操作.分享给大家供大家参考,具体如下: 创建fruits表: CREATE TABLE fruits ( f_id char(10) NOT NULL, s_id INT NOT NULL, f_name char(255) NOT NULL, f_price decimal(8,2) NOT NULL, PRIMARY KEY(f_id) ) ; INSERT INTO fruits (f_id, s_id, f_name, f_price) VALUES(

  • MySQL多表查询实例详解【链接查询、子查询等】

    本文实例讲述了MySQL多表查询.分享给大家供大家参考,具体如下: 准备工作:准备两张表,部门表(department).员工表(employee) create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'ma

  • MySQL单表查询操作实例详解【语法、约束、分组、聚合、过滤、排序等】

    本文实例讲述了MySQL单表查询操作.分享给大家供大家参考,具体如下: 语法 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名                   WHERE 条件                   GROUP BY field                   HAVING 筛选                   ORDER BY field                   LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键

  • 解析Mysql多表查询的实现

    查询是数据库的核心,下面就为您介绍Mysql多表查询时如何实现的,如果您在Mysql多表查询方面遇到过问题,不妨一看.Mysql多表查询: 复制代码 代码如下: CREATE TABLE IF NOT EXISTS contact( contact_id int(11) NOT NULL AUTO_INCREMENT, user_name varchar(255), nom varchar(255), prenom varchar(255), mail varchar(64), passcode

  • MySQL联表查询的简单示例

    MySql会用到联表查询,对于刚学习的新手来说,可能会理解起来有难度.下面这篇文章就来给大家详细介绍MySQL联表查询的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 关系型数据库,免不了表之间存在各种引用与关联.这些关联是通过主键与外键搭配来形成的.所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的操作. MySQL 中 JOIN, CROSS JOIN 和 INNER JOIN 三者语法功能上相同,可

  • MySQL联表查询基本操作之left-join常见的坑

    概述 对于中小体量的项目而言,联表查询是再常见不过的操作了,尤其是在做报表的时候.然而校对数据的时候,您发现坑了吗?本篇文章就 mysql 常用联表查询复现常见的坑. 基础环境 建表语句 DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_name` VARCHAR(50) DEFAULT NULL COMMENT '角色名', PRIMARY KEY (`i

  • MySQL多表查询详解下

    好好吃饭,好好休息,听着很简单,实际落实缺失不那么容易. 继续回顾MySql的多表查询之1999语法 #二,SQL1999语法 语法: SELECT 查询列表 FROM 表1 别名 [连接类型] JOIN 表2 别名 ON 链接条件 [WHERE 筛选条件] [GROUP BY 分组] [HAVING 筛选条件] [ORDER BY 排序列表ASC|DESC] 分类(连接类型): 内连接(★): INNER 外联结 左外(★):LEFT [OUTER] 右外(★):RIGHT [OUTER] 全

  • MySQL多表查询详解上

    时光在不经意间,总是过得出奇的快.小暑已过,进入中暑,太阳更加热烈的绽放着ta的光芒,...在外面被太阳照顾的人们啊,你们都是勤劳与可爱的人啊.在房子里已各种姿势看我这篇这章的你,既然点了进来,那就由我继续带你回顾MySql的知识吧! 回顾练习资料girls库以及两张表的脚本: 链接: https://pan.baidu.com/s/1bgFrP7dBBwk3Ao755pU4Qg 提取码: ihg7 引题:笛卡尔现象,先来观看一下两张表. SELECT * FROM boys; SELECT *

  • MySQL单表查询实例详解

    1.准备数据 以下操作将在该表中进行 create table student ( id int unsigned primary key auto_increment, name char(12) not null, gender enum("male","famale") default "male", age tinyint unsigned not null, hoc_group char(12) not null, html tinyi

随机推荐