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 一个简单的嵌套循环连 ...
随机推荐
- request和response——请求响应对象
请求对象--request 获取get请求的值 一次请求,返回一个响应. 地址栏:http://127.0.0.1:8000/day3/get_request?lan=python 问号:代表请求参数 ...
- 记录NLTK安装使用全过程--python
前言 之前做实验用到了情感分析,就下载了一下,这篇博客记录使用过程. 下载安装到实战详细步骤 NLTK下载安装 先使用pip install nltk 安装包 然后运行下面两行代码会弹出如图得GUI界 ...
- Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?
首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>(); hs.add("hello"); ...
- mac安装git
https://blog.csdn.net/shaock2018/article/details/91127607 继续报错 rm -rf /usr/local/Homebrew/Library/Ta ...
- callbale 和runnable 区别
Callable接口: 1 2 3 public interface Callable<V> { V call() throws Exception; } Runnable接口: ...
- 99%的人都搞错了的java方法区存储内容,通过可视化工具HSDB和代码示例一次就弄明白了
https://zhuanlan.zhihu.com/p/269134063 番茄番茄我是西瓜 那是我日夜思念深深爱着的人啊~ 已关注 6 人赞同了该文章 前言 本篇是java内存区域管理系列教 ...
- SQLyog创建用户并授权的过程
点击你要授权的数据库然后点击用户管理器 然后输入用户名和密码主机选localhost 然后点击创建,然后选择你创建的数据库全选 最后保存就可以了
- 学习Cobbler(一)
一. http://cobbler.github.io/ Cobbler is a Linux installation server that allows for rapid setup of n ...
- docker学习-01-安装docker
[root@localhost firstDocker]# cat /etc/centos-release CentOS Linux release 7.6.1810 (Core) [root@loc ...
- Python - Python函数简介
