加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

ABAP基础知识不一样的leftjoin

(2023-02-18 19:56:36)
标签:

abap

alv

f4

liumeng

sap

分类: 数据库相关
文章转自:
ABAP基础知识不一样的leftjoin

前言

LEFT JOIN 表示显示左表的全部及关联右表的部分,实际处理时,如果关联的关键字在左表只有一条,但是在右表有N条,

  • 结果集显示1条(当右表没有或只有1条时, N=1或0)

  • 结果集显示N条(当右表有多条,N>1)

在解决不同字段内容关联的问题时,无意中看到LEFT JOIN 的附加语法MANY TO ONE .本来以为该语法可以达成仅关联一条的效果.实际测试却发现并发如此.


本文主要介绍LEFT JOIN 中MANY TO ONE 的特点及用法


左连接示意图

该示意图未表达连接部分增加记录数的特性. 


ABAP基础知识不一样的leftjoin

MANY TO ONE 语法介绍

下图是ABAP语法帮助中关于MANY TO ONE 的描述



ABAP基础知识不一样的leftjoin

演示数据

测试: 物料 TEST20210203/1 在MARA 中有一行 , 在MARC中有两行.

ABAP基础知识不一样的leftjoin

测试场景

以下测试使用 HANA SQL 语句. ABAP SQL语句与之类似. 

HANA中使用left out join  ABAP中使用 left join  .

嵌套SQL的实现方式有很大的差异. 


01

场景一

 包含两个表的字段.

select a.matnr,b.matnr from mara as a left outer many to one join  marc as b on b.mandt = a.mandt and b.matnr = a.matnr

where a.matnr = 'TEST20210203/1'

结果: 显示两行


02

场景二


仅包含MARA字段


select a.matnr from mara as a left outer many to one join  marc as b on b.mandt = a.mandt and b.matnr = a.matnr

where a.matnr = 'TEST20210203/1'

结果:仅显示一行


03

场景三

计数(*)

select count( * ) from mara as a left outer many to one join  marc as b on b.mandt = a.mandt and b.matnr = a.matnr

where a.matnr = 'TEST20210203/1'

结果:返回值 1.


04

场景四 


group 左表字段 count

select a.matnr,count( * ) from mara as a left outer many to one join  marc as b on b.mandt = a.mandt and b.matnr = a.matnr

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  marc as b on b.mandt = a.mandt and b.matnr = a.matnr

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  a.matnr,c.ekgrp ,

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 语句关联相关表, 根据字段所在的表,数据库系统自动判断是否需要关联右表(这个说法不一定准确,仅从测试的表现判断的,实际上数据库可能使用其它机制).



 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有