MySQL多表查询带来的重复记录问题
在开发中因为不谨慎遇到了这样一个问题,这里总结一下问题、问题出现的原因和解决方式。
假如现在有这么一个需求,
表1
表2
想要从表1中筛选出masterMerchantNo或slaveMerchantNo其中任意一个字段的值等于表2的merchantNo(也就是在表2中的merchantNo中存在这个值)的所有记录的表1的相关信息。
所以我一开始想到的是两表查询然后过滤条件,也就是两个条件OR就可以了(tb1.masterMerchantNo = tb2.merchantNo OR tb1.slaveMerchantNo = tb2.merchantNo),原先编写的sql如下:
SELECT
tb1.batchNo,
tb1.masterSettleUnitID,
tb1.masterMerchantNo,
tb1.slaveSettleUnitID,
tb1.slaveMerchantNo,
tb1.activityType,
tb1.operatorInfo,
tb1.submitTime,
tb1.bindStatus,
tb1.returnCode,
tb1.returnMsg,
tb1.unbindTime
FROM
tbl_fsm_settle_activity_mergeRecord tb1
INNER JOIN (
SELECT
merchantNo
FROM
tbl_fsm_settle_unit
WHERE
groupID = 1155
AND openPayStatus = 40
) tb2 ON tb1.masterMerchantNo = tb2.merchantNo
OR tb1.slaveMerchantNo = tb2.merchantNo
WHERE
action in ( 0 , 1 )
然后发现了问题,正常按照需求想要的结果应该是筛选后只有一条记录,就是表1这样的一条,然而如果是上面这样的sql的话,执行完后会得到两条记录,而且两条记录是一模一样的。。这显示不是我们想要的。
思考了下,发现原因,像上面这样的写法的话,sql执行首先会生成笛卡儿积,表1*表2,也就是1*2=2,总共生成2条记录,笛卡儿积应该如下:
然后在对上图所示笛卡儿积进行条件(tb1.masterMerchantNo = tb2.merchantNo OR tb1.slaveMerchantNo = tb2.merchantNo)过滤,所以这样就会得到两条重复的结果。。
所以解决这个问题的方式就是要避免笛卡儿积,所以我们避免使用多表查询sql,可以使用如下的sql:
SELECT
batchNo,
masterSettleUnitID,
masterMerchantNo,
slaveSettleUnitID,
slaveMerchantNo,
activityType,
operatorInfo,
submitTime,
bindStatus,
returnCode,
returnMsg,
unbindTime
FROM
tbl_fsm_settle_activity_mergeRecord
WHERE
action IN (0, 1)
AND (
masterMerchantNo IN (
SELECT
merchantNo
FROM
tbl_fsm_settle_unit
WHERE
groupID = 1155
AND openPayStatus = 40
)
OR slaveMerchantNo IN (
SELECT
merchantNo
FROM
tbl_fsm_settle_unit
WHERE
groupID = 1155
AND openPayStatus = 40
)
)
这样就可以避免笛卡儿积,来得到我们想要的结果。
- 用Metaclass实现一个精简的ORM框架
- HDU 2504 又见GCD(最大公约数与最小公倍数变形题)
- Selenium2+python自动化63-二次封装(click/send_kesy)
- Selenium2+python自动化65-js定位几种方法总结
- HDU 2502 月之数(二进制,规律)
- Tensorflow实战系列:手把手教你使用CNN进行图像分类(附完整代码)
- HDU 2503 a/b + c/d(最大公约数与最小公倍数,板子题)
- python接口自动化6-重定向(Location)
- 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
- python接口自动化7-参数关联
- 深度学习GPU环境Ubuntu16.04+GTX1080+CUDA9+cuDNN7+TensorFlow1.6环境配置
- python接口自动化8-参数化
- HDU 2037 今年暑假不AC(贪心,区间更新,板子题)
- “玲珑杯”ACM比赛 Round #13 题解&源码
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- SwiftUI:使用 @EnvironmentObject 从环境中读取自定义值
- JavaScript 启动性能瓶颈分析与解决方案
- 大白话理解Vuex
- 【Java面试总结】计算机网络
- volatile关键字 Krains 2020-08-26
- synchronized关键字 Krains 2020-08-25
- happens-before Krains 2020-08-26
- ReentrantLock可重入锁 Krains 2020-08-27
- Java中的线程 Krains 2020-08-24
- CAS Krains 2020-08-25
- 96. 不同的二叉搜索树 II Krains 2020-09-03 树
- 410. 分割数组的最大值 Krains 2020-08-29 20:21:39 动态规划二分查找
- 字典树 Krains 2020-09-01
- redis学习(十)
- vue修改浏览器的标题title