MySQL left join 引发的惨案
当我用这个进行更改值时,type未控制order表 其他数据被更改 还好备份数据表了(这里就体现了备份的重要性)
UPDATE expense_order as a
left join (
SELECT detail.company_id,detail.`order_id`,sum(detail.`deduction_money`) as amount FROM expense_amortize_detail as detail
JOIN `pigcms_expense_order` as expense on expense.`id` = detail.`order_id`
WHERE detail.`company_id` =336 and detail.`status` = 0
and expense.`company_id` =336 and expense.type=2 and expense.is_parent = 1 and expense.status in (1,2) and expense.auditing_status = 1
GROUP BY(expense.`id`) ORDER BY expense.`id` DESC
) as d
on a.id =d.order_id and a.company_id = d.company_id and a.type =2
set a.settlement_money=d.amount;
还原表数据 同样left join 不同之处在于通过 where控制左联表的判断依据
UPDATE expense_order as a
left join expense_order_bak as bak
on a.id =bak.id
set a.settlement_money=bak.settlement_money
where a.type=1
其他解决方案 将left join 更改为inner join
UPDATE expense_order as a
inner join (
SELECT detail.company_id,detail.`order_id`,sum(detail.`deduction_money`) as amount FROM expense_amortize_detail as detail
JOIN `pigcms_expense_order` as expense on expense.`id` = detail.`order_id`
WHERE detail.`company_id` =336 and detail.`status` = 0
and expense.`company_id` =336 and expense.type=2 and expense.is_parent = 1 and expense.status in (1,2) and expense.auditing_status = 1
GROUP BY(expense.`id`) ORDER BY expense.`id` DESC
) as d
on a.id =d.order_id and a.company_id = d.company_id and a.type =2
set a.settlement_money=d.amount;
案例
localhost 新建 blog_cate 栏目表 blog_artcle 文章表
-- 删除blog库
DROP DATABASE IF EXISTS blog;
-- 新建blog库
CREATE DATABASE blog charset utf8;
-- 查看、进入
show database;
use blog;
-- 先删后建栏目表
drop table if exists blog_cate ;
create table blog_cate (
id INTEGER,
catename varchar(30)
);
-- 同理 建文章表blog_artcle
--- 插入数据
INSERT INTO `blog_cate `(`id`, `catename `) VALUES (1, '父亲的散文诗');
INSERT INTO `blog_cate `(`id`, `catename `) VALUES (2, '心情文字');
INSERT INTO `blog_artcle`(`id`, `title`, `desc`, `content`, `cateid`, `time`, `pic`) VALUES (1, 'test', '测试测试', '父亲的散文诗', 1, 2022, 'dd');
INSERT INTO `blog_artcle`(`id`, `title`, `desc`, `content`, `cateid`, `time`, `pic`) VALUES (2, 'test1', '测试测试1', '父亲的散文诗1', 1, 2022, 'dd');
INSERT INTO `blog_artcle`(`id`, `title`, `desc`, `content`, `cateid`, `time`, `pic`) VALUES (4, 'test4', '测试测试4', '父亲的sf散文诗1', 2, 2022, 'dd');
INSERT INTO `blog_artcle`(`id`, `title`, `desc`, `content`, `cateid`, `time`, `pic`) VALUES (3, 'test3', '测试测试3', 'dfsfsfs', 2, 2022, 'dd');
blog_cate

blog_artcle

数据库连表方式
- 内连接 :inner 、inner join
- 外连接 :outer join
- 左外连接 :left outer join
- 左连接 :left join
- 右外连接 right outer join
- 右连接: right join
- 全连接 full join 、union
内连接
查询的是两张表的并集,也就是A表和B表都必须有数据才能查询出来;
/*** 栏目的id 与 文章的所属栏目id */
-- join
select * from blog_cate as c join blog_artcle as a on c.id = a.cateid
-- inner join
select * from blog_cate as c inner join blog_artcle as a on c.id = a.cateid
-- 逗号的连表方式就是内连接
select * from blog_cate as c, blog_artcle as a where c.id = a.cateid
/**栏目的id 与 文章的id 进行查询*/
select * from blog_cate as c inner join blog_artcle as a on c.id = a.id
结果展示


左外连接 和 左连接
是以左表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将左表所有的查询信息列出,而右表只列出ON后条件与左表满足的部分。左连接全称为左外连接,是外连接的一种。
/*** 栏目的id 与 文章的id */
-- left join
select * from blog_cate as c left join blog_artcle as a on c.id = a.id
-- left outer join
select * from blog_artcle as c left outer join blog_cate as a on c.id = a.id
-- left join

-- left outer join 两个表更换位置

右外连接 和 右连接
是以右表为基础,根据ON后给出的两表的条件将两表连接起来。结果会将右表所有的查询信息列出,而左表只列出ON后条件与右表满足的部分。右连接全称为右外连接,是外连接的一种。
-- right join
select * from blog_cate as c right join blog_artcle as a on c.id = a.id
-- right outer join
select * from blog_artcle as c right outer join blog_cate as a on a.id = c.id
与上面左联接进行比较
-- right join 两个表更换位置

-- right outer join

全连接
全连接显示两侧表中所有满足检索条件的行。
mysql中没有full join,mysql可以使用union实现全连接;
select * from blog_cate as c left join blog_artcle as a on a.id = c.id
union
select * from blog_cate as c right join blog_artcle as a on c.id = a.cateid

实验 今日出现的问题
步骤1 定目标
-- 修改文章cateid 为2的内容 为所属栏目的name
UPDATE blog_artcle as a
LEFT JOIN blog_cate as c
on a.cateid = c.id and a.cateid = 2
SET a.content = c.catename
步骤2 首先看下原表内容
SELECT * FROM blog_artcle
步骤3 执行 查看差异

有2行被修改,但是cateid=1的直接被修改到为null 可知and a.cateid = 2 这个 条件我们没有控制到 cateid=1的数据已被更改为null

步骤4 更改SQL语句
--- left join 与 where 结合 改cateid =2 的
UPDATE blog_artcle as a
LEFT JOIN blog_cate as c
on c.id = a.cateid
SET a.content = c.catename WHERE a.cateid = 2
--- inner join 与on 结合 改cateid =1 的
UPDATE blog_artcle as a
inner JOIN blog_cate as c
on a.cateid = c.id and a.cateid =1
SET a.content = c.catename
成功

右连接可参考左联接 这里就完结了 今天圆满一天
MySQL left join 引发的惨案的更多相关文章
- 记一次真实的线上事故:一个update引发的惨案!
目录 前言 项目背景介绍 要命的update 结语 前言 从事互联网开发这几年,参与了许多项目的架构分析,数据库设计,改过的bug不计其数,写过的sql数以万计,从未出现重大纰漏,但常在河边走,哪 ...
- MySQL Left Join,Right Join
魂屁,东西发这里了关于Left Join,Right Join的 在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧(如果内容有错误或有疑问, ...
- MySQL Full Join的实现
MySQL Full Join的实现 由于MySQL不支持FULL JOIN,以下是替代方法 left join + union(可去除反复数据)+ right join select * from ...
- mysql left join
MySQL左连接不同于简单连接.MySQL LEFT JOIN提供该表额外字段在左侧. 如果使用LEFT JOIN,得到的所有记录的匹配方式相同, 在左边表中得到的每个记录不匹配也会有一个额外的记录. ...
- MySQL的JOIN(一):用法
JOIN的含义就如英文单词"join"一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. CREATE TABLE ...
- MySQL的JOIN(三):JOIN优化实践之内循环的次数
这篇博文讲述如何优化内循环的次数.内循环的次数受驱动表的记录数所影响,驱动表记录数越多,内循环就越多,连接效率就越低下,所以尽量用小表驱动大表.先插入测试数据. CREATE TABLE t1 ( i ...
- MySQL的JOIN(四):JOIN优化实践之快速匹配
这篇博文讲述如何优化扫描速度.我们通过MySQL的JOIN(二):JOIN原理得知了两张表的JOIN操作就是不断从驱动表中取出记录,然后查找出被驱动表中与之匹配的记录并连接.这个过程的实质就是查询操作 ...
- MySQL的JOIN(五):JOIN优化实践之排序
这篇博文讲述如何优化JOIN查询带有排序的情况.大致分为对连接属性排序和对非连接属性排序两种情况.插入测试数据. CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_I ...
- Mysql Nested-Loop Join Algorithms
MySQL在多表之间执行join时,利用一种nested-loop algorithm 或者其变种:(嵌套循环) Nested-Loop Join Algorithm 一个简单的嵌套循环连 ...
随机推荐
- 什么是Spring Cloud Bus?
spring cloud bus 将分布式的节点用轻量的消息代理连接起来,它可以用于广播配置文件的更改或者服务直接的通讯,也可用于监控. 如果修改了配置文件,发送一次请求,所有的客户端便会重新读取配置 ...
- SpringBoot与SpringCloud的关系与区别?
一.SpringBoot和SpringCloud简介 1.SpringBoot:是一个快速开发框架,通过用MAVEN依赖的继承方式,帮助我们快速整合第三方常用框架,完全采用注解化(使用注解方式启动Sp ...
- 为什么要用 Spring Boot?
Spring Boot 优点非常多,如:独立运行简化配置自动配置无代码生成和XML配置应用监控上手容易Spring Boot 集这么多优点于一身,还有理由不使用它呢?
- jvm-learning-类加载子系统
类加载子系统的作用 类加载器ClassLoader角色 类的加载过程(广义加载) 加载 加载.class文件的方式 连接Linker 初始化 注意:如果类种没有变量赋值动作和静态代码块的语句是不 ...
- JDBC的全称是什么?
Java DataBase Connectivity,java数据库连接
- ArrayList分别与LinkedList、Vector、Array的区别
ArrayList与LinkedList的区别 ArrayList底层是一个动态数组,LinkedList底层是双向链表 当随机访问List时(get和set操作),ArrayList比LinkedL ...
- 学习openstack(七)
相关资料: https://www.cnblogs.com/shhnwangjian/category/942049.html https://www.cnblogs.com/goodcook/cat ...
- C语言之main方法解析(知识点1)
1.注释 /*自带注释*/2.引包 #include <stdio.h>3.主方法 void main{}4.执行体 printf("打印& ...
- 时间工具类之"获取相差天数"
一.时间工具类DateUtils之"获取相差天数" 1 /** 2 * 相差天数 3 * 4 * <p>TODO 方法功能描述 5 * 6 * @param start ...
- (stm32f103学习总结)—GPIO结构
一.GPIO基本结构 二.GPIO工作模式 输入模式 输入浮空 输入上拉 输入下拉 模拟输入 输出模式 开漏输出 开漏复用功能 推挽式输出 推挽式复用功能 库函数中所对应的代码 1 typedef e ...
