mysql 左联left join解析及使用指南

  left join在数据库编程应用中使用频率较高,而且合理使用left join有时会大大提高sql性能,降低编程复杂度。left join通常用于行记录信息补全,将子查询转换为一个大查询,将多个case查询转换为一个查询等。关于left join本文讨论以下几个知识点:

  • left join语法
  • left join 工作原理
  • left join 应用场景

  关于Mysql join,left join 更多知识当然建议大家翻阅mysql 参考手册,下述2篇也可以简单了解下:
1)MySQL的连接查询:left join , right join , join
2)关于 MySQL LEFT JOIN 你可能需要了解的三点

1、left join语法

使用sql进行join连接时,无非2种使用方式:
1)select … from a, b, c left join d on where …
2)select … from a inner join b on… inner join c on … left join d on … where …
建议使用方式2,sql简单明了,可以处理多表复杂left join,本文left join sql语法都使用方式2。

2、left join 工作原理

SELECT distinct a.sid, a.goods_id,
    a.goods_no, a.goods_type, a.goods_name, a.spec, 
    a.is_onsale, a.unit_id, c.unit_name,
    a.catg_id, d.catg_name, d.fullname catg_fullname,
    e.bom_id, e.bom_no 
FROM base_goods a 
inner join base_goods_unit c on a.co_id = c.co_id and c.unit_id = a.unit_id 
left join base_goods_catg d on a.catg_id = d.catg_id and a.co_id = d.co_id 
left join base_goods_bom e on a.co_id = e.co_id and a.goods_id  = e.goods_id and e.status = '有效'
WHERE a.co_id = 10 AND a.is_deleted ='N' and goods_type = '成品' and is_onsale = 'Y'
  • ON 条件(left join base_goods_bom e on a.co_id = e.co_id and a.goods_id = e.goods_id and e.status = ‘有效’)用来决定如何从 e 表中检索数据行。匹配成功则取e表的bom_id,bom_no否则用null填充;
  • 在ON匹配阶段 WHERE 子句的条件都不会被使用。匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。

3、left join 常见应用场景

1)补充数据,完善行记录信息

上文的取产品bom号就是扩展产品信息典型案例。

2)将not in子查询转换为一个大查询

继续上文的案例,找出没有BOM的成品。
使用not in子查询方式:

SELECT distinct a.sid, a.goods_id, a.goods_no, a.goods_type, a.goods_name, a.spec 
FROM base_goods a 
WHERE a.co_id = 10 AND a.is_deleted ='N' and goods_type = '成品' and is_onsale = 'Y'
and a.goods_id not in (select goods_id from base_goods_bom e where e.co_id = '10' and e.status ='有效')

使用left join方式:

SELECT distinct a.sid, a.goods_id, a.goods_no, a.goods_type, a.goods_name, a.spec, e.bom_no
FROM base_goods a left join base_goods_bom e on a.co_id = e.co_id and a.goods_id = e.goods_id and e.status = '有效'
WHERE a.co_id = 10 AND a.is_deleted ='N' and goods_type = '成品' and is_onsale = 'Y' and e.bom_no is null
3) 多个case的sql合并成一个sql
select a.client_id, a.client_no, a.client_name, 
b.balance as discount, b1.balance as jiegai,b2.balance as mianpin,
b3.balance as baosun 
from sale_client a 
LEFT JOIN sale_account_discount b on a.client_id = b.client_id 
	and a.co_id = b.co_id and b.discount_type = '折扣' 
LEFT JOIN sale_account_discount b1 on a.client_id = b1.client_id 
	and a.co_id = b1.co_id and b1.discount_type = '揭盖'
LEFT JOIN sale_account_discount b2 on a.client_id = b2.client_id 
	and a.co_id = b2.co_id and b2.discount_type = '免品'
LEFT JOIN sale_account_discount b3 on a.client_id = b3.client_id 
	and a.co_id = b3.co_id and b3.discount_type = '报损'
where a.co_id = 10 and a.client_id = 113;

上述sql为获取client=113客户的折扣、揭盖、免品、报损台账余额,如果不使用left join,我们只能逐个台账类型获取,获取4遍,如下:

select a.client_id, a.client_no, a.client_name, b.balance as discount
from sale_client a 
inner JOIN sale_account_discount b on a.client_id = b.client_id 
	and a.co_id = b.co_id and b.discount_type = '折扣' 
where a.co_id = 10 and a.client_id = 113;
-- 免品、揭盖、报损

你可能感兴趣的:(Database,Mysql,SQL,Hack,Mysql,left,join,子查询,case)