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 一个简单的嵌套循环连 ...
随机推荐
- nacos底层原理
Nacos 为什么选择NacosNacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. Nacos 帮 ...
- Windows 10 安装 wordpress
如何在Windows上安装wordpress. 安装前准备: 安装并配置好Apache httpd及PHP,见<Windows10安装PHP7+Apache 2.4>. 安装好MySQL, ...
- 如何设置出IDEA中VCS下的Enable Version Control Intergration
File–>settings–>Version Control
- Idea学习之"使用SVN如何查看哪一行是哪一个人写的历史日志"
点击出的方法 结果图 点击记录,显示详细
- 【二次元的CSS】—— 纯CSS3做的能换挡的电扇
这次分享的电扇,和以往用css3画人物相比 多加了一点交互,就是电扇开关的地方,用到了一点点css3的 :checked +div 这个很少用到的选择器来实现的. GitHub传送门:https:// ...
- HTML5 Canvas学习之路(六)
一个炫酷的计时器 在慕课网看到一个canvas的课,感觉很炫酷,就把它看完了,然后记下来.http://www.imooc.com/learn/133 第一步:绘制要显示的时间 拿小球来绘制具体的数字 ...
- Python窗口学习之搜索框美化
初学tkinter,感觉这个插件虽然是做界面的,但是没有html,也没有android那么人性化 既没有画圆角长方形的办法也没有添加透明按钮的办法(可能是我没找到) 所以自己用canvas画了两个扇形 ...
- TensorFlow使用GPU训练时CPU占用率100%而GPU占用率很低
在训练keras时,发现不使用GPU进行计算,而是采用CPU进行计算,导致计算速度很慢. 用如下代码可检测tensorflow的能使用设备情况: from tensorflow.python.clie ...
- 一个chome的广告拦截小插件
先附上下载地址:https://chromecj.com/productivity/2015-03/391.html 可以屏蔽绝大多数广告啊,浏览器用起来神清气爽! 下载完成后有一个名字为这个的文件, ...
- 在tomcat布置项目
1.将项目打成war包复制到tomcat-webapps 2.修改tomcat端口号 3.指定jdk 一.找到tomcat目录/bin 文件夹下的 catalina.bat文件 二.在文件中找到 ec ...