ABAP基础知识不一样的leftjoin

标签:
abapalvf4liumengsap |
分类: 数据库相关 |

一
前言
LEFT JOIN 表示显示左表的全部及关联右表的部分,实际处理时,如果关联的关键字在左表只有一条,但是在右表有N条,
-
结果集显示1条(当右表没有或只有1条时, N=1或0)
-
结果集显示N条(当右表有多条,N>1)
在解决不同字段内容关联的问题时,无意中看到LEFT JOIN 的附加语法MANY TO ONE .本来以为该语法可以达成仅关联一条的效果.实际测试却发现并发如此.
本文主要介绍LEFT JOIN 中MANY TO ONE 的特点及用法
二
左连接示意图
该示意图未表达连接部分增加记录数的特性.

四
演示数据
测试: 物料 TEST20210203/1 在MARA 中有一行 , 在MARC中有两行.
五
测试场景
以下测试使用 HANA SQL 语句.
HANA中使用left out join
嵌套SQL的实现方式有很大的差异.
01
场景一
select a.matnr,b.matnr from mara as a left outer many to one join
where a.matnr = 'TEST20210203/1'
结果: 显示两行
02
场景二
仅包含MARA字段
select a.matnr from mara as a left outer many to one join
where a.matnr = 'TEST20210203/1'
结果:仅显示一行
03
场景三
计数(*)
select count( * ) from mara as a left outer many to one join
where a.matnr = 'TEST20210203/1'
结果:返回值 1.
04
场景四
group 左表字段 count
select a.matnr,count( * ) from mara as a left outer many to one
join
where a.matnr = 'TEST20210203/1'
group by a.matnr
结果:统计值 1
05
场景五
group 右表字段 count
select b.matnr,count( * ) from mara as a left outer many to one
join
where a.matnr = 'TEST20210203/1'
group by b.matnr
结果:统计值 2
六
结论
SQL 会根据SELECT LIST 的字段确定是否优化结果的获取. 如果字段没有涉及到 右表, 则视同为没有关联右表,如果涉及到, 再关联右表.
七
用途
似乎没啥用. Left outer join 右表 的目的肯定是要从表中获取数据呀.
唯一的作用, 动态SQL时, 会根据动态设定的字段来确定读取的数据的条目数.
仔细思考了该语法的业务用途:
这个语句可以让SQL根据字段的需求自行判断返回的结果集数量.
比如只获取左表内容(抬头表). 则返回抬头一行
如果包含了明细表字段, 则返回明细多行,如果没有明细,返回抬头一行
八
扩展
如果我们关联的右表有多条记录,结果集中包含右表的字段,但是只想显示一条.(第一眼误会MANY TO ONE 子句含义,想达成的目的)
此时针对不同的考虑,应用不同的处理方式
01
获取任意一个工厂
考虑使用 SELECT MATNR,MAX( WERKS) 或 MIN(WERKS).
select a.matnr,max( c.werks ) from mara as a
left outer join marc as c on c.mandt = a.mandt and c.matnr = a.matnr
where a.matnr = 'TEST20210203/1'
group by a.matnr
02
多个工厂的采购组一样
考虑使用 SELECT DISTICT MATNR,EKGRP 但这样做的风险在于, 一旦出现地点的采购组不通的情况, 结果集就会返回多条记录了
select distinct a.matnr,c.ekgrp from mara as a
left outer join marc as c on c.mandt = a.mandt and c.matnr = a.matnr
where a.matnr = 'TEST20210203/1'
03
获取最大工厂号的采购组
则需要使用 rank() 及嵌套SQL 语句了
select * from
( select
rank( ) over( partition by a.matnr order by werks desc ) as zrank
from mara as a
left outer join marc as c on c.mandt = a.mandt and c.matnr = a.matnr
)
where matnr = 'TEST20210203/1' and zrank = 1
如果时最小工厂号,则去掉werks 后面的 desc(表示倒排序)
九
总结
LEFT OUTER JOIN 中的 MANY TO ONE 子句是动态读取抬头表和明细表的SQL语句的一个较为简洁的表达方式.
无需根据查询的字段 动态设置 FROM 子句内容.
用 LEFT OUTER MANY TO ONE 语句关联相关表, 根据字段所在的表,数据库系统自动判断是否需要关联右表(这个说法不一定准确,仅从测试的表现判断的,实际上数据库可能使用其它机制).