SQL匹配条件不起作用怎么回事?----SQL左连接,右连接和内连接的条件放置位置

实际很多时候写代码写的都是业务代码,业务代码又以SQL最为常见。根据业务我们会设置很多关于连接的地方,左连接,右连接,内连接的使用不当很可能导致SQL达不到预期,可能给人感觉“SQL执行只走了一半”或者“中间有的地方跳过去,条件没有匹配返回的结果集是错误的”

一 问题
首先要知道左连接 右连接 内连接区别
我们以左连接作为例子,
A left join B -------》A B 左连接,也就是左边的变为主表 也就是A的数据全数取出,能跟B对应得上,B表的扩展数据也跟着展示出来,A有B没有的,B表的扩展字段也展示出来,只不过展示的是null而已。

这时候我们有的时候会在ON的后面加条件,不管你是在AND A.XXX = xxx 还是 WHERE B.XXX = xxx,你会发现有的时候这个条件加了也白加。

为什么?拿左连接为例子,你在LEFT JOIN ON A.id = B.id 后面添加关于A或者B的条件,比如说A.name=“ZP真帅”,你会发现这个筛选条件没有作用 name="李四真帅"也出来了。因为在ON后面的条件不管是A的还是B的,返回的结果是什么,都会把主表数据先列出来。

解决方式把条件不要放在有关联的ON后面,当然是放在where里面最好,也可以放在别的不相关的关联后面。

二 实际例子以及解决方式
这个例子就是把两个条件(uvr.user_id = 10023 ,uvr.target_type = 2)放在第一个左连接后面还是放在where后面都不生效,其中一个问题是左连接ON后面条件失效的问题还有一个关于是OR的问题

SELECT
	uvr.id,
	uvr.user_id,
	uvr.target_type,
	uvr.target_id,
	uvr.create_time,
	ui.head_img_url AS avatar,
	temp.`goods_name`,
	temp.head_img_url,
	temp.second_hand_price,
	ud.type 
FROM
	user_view_record uvr
	LEFT JOIN user_info ui ON uvr.user_id = ui.id
	AND uvr.user_id = 10023
	AND uvr.target_type = 2

	INNER JOIN goods temp ON uvr.target_id = temp.id
	LEFT JOIN user_detail ud ON uvr.user_id = ud.user_id 
WHERE
	uvr.user_id < 100000 OR uvr.user_id > 200000 
ORDER BY
	create_time DESC

解决后的代码
其实不是很建议我下面的方法,还是最好把条件放在where里面,出现where后面的条件不生效是因为 OR的问题,你把它当成正常的代码分析一下逻辑就知道,解决也很好解决,加个括号什么的就好了。

SELECT
	uvr.id,
	uvr.user_id,
	uvr.target_type,
	uvr.target_id,
	uvr.create_time,
	ui.head_img_url AS avatar,
	temp.`goods_name`,
	temp.head_img_url,
	temp.second_hand_price,
	ud.type 
FROM
	user_view_record uvr
	LEFT JOIN user_info ui ON uvr.user_id = ui.id
	INNER JOIN goods temp ON uvr.target_id = temp.id 
	AND uvr.user_id = 10023 
	AND uvr.target_type = 2
	LEFT JOIN user_detail ud ON uvr.user_id = ud.user_id 
WHERE
	uvr.user_id < 100000 OR uvr.user_id > 200000 
ORDER BY
	create_time DESC
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值