inner join 前提是两个表有相同的Key可作为关联,
比如 EKKO&EKPO ->EKKO INNER JOIN EKPO ON EKKO~EBELN = EKPO~EBELN.
另外:BKPF&BSEG虽然有共同的Key,但是SAP不允许用Inner Join去读取它们,可能是考虑到这两个表太大了吧。
当两个表不能用Inner Join的时候,用 for all entries in T_TEMP:
1. 使用该语句前,必须对T_TEMP按Key排序,并删除重复项。
2.使用该语句,对于最后得出的结果集系统会自动删除重复行。因此如果你要保留重复行记录时,记得在SELECT语句中添加足够键值项目(有必要时,增加全部键值项目),以保
证结果集中所需重复项目不会被删除。(例如选取支付金额时,支付事件可能不同,但金额可能相同,此时一定要注意,以避免错误删除结果记录。)
3.FOR ALL ENTRIES IN后面使用的内部表itab如果为空,系统将视为无条件选取,将当前CLIENT下所有记录选出。因此为避免无意义的全件检索,在使用该语句前一定要判断内部
表itab是否为空,为空时不执行包含该语句的数据库检索处理。
4.由于itab-f实际上是作为占位符被替换,所以内部表itab中不要包含HEADER行(项目标识名称行),以免造成混淆,检索出错。
5.内部表itab中作为条件替换用项目的类型和长度,一定要和检索数据库中对应的项目相同,否则编译不能通过。
6.对于内部表itab中作为条件替换用项目,不能使用LIKE,BETWEEN,IN比较操作符。因为这些比较操作符都是不确定比较操作符(将选择条件设定在一个范围内),而FOR ALL
ENTRIES IN语句的作用相当于将选择条件块全部并列开来,用OR连接,如果每个OR分支中又是不确定的范围,那么系统性能将大大降低,因此R/3系统在使用该语句时禁止使用不确
定比较操作符。
7.使用该语句时,ORDER BY语句和HAVING语句将不能使用。
8.使用该语句时,除COUNT( * )以外的所有合计函数(MAX,MIN,AVG,SUM)都不能使用。
举一个简单的例子:
查询PO的料号和数量,同时要看到料号主档当前的描述:
那么取数顺序就是
REFRESH:T_EKPO,T_EKPO_TEMP,T_MAKT.
SELECT EKKO~EBELN EKPO~EBELP EKPO~MENGE EKPO~MEINS
FROM EKKO INNER JOIN EKPO ON EKKO~EBELN = EKPO~EBELN
WHERE EKKO~EBELN = '50000000000' ."示例号码,实际程序来源屏幕选项
T_EKPO_TEMP[] = T_EKPO[].
SORT T_EKPO_TEMP BY MATNR .
DELETE ADJACENT DUPLICATES FROM T_EKPO_TEMP COMPARING MATNR .
IF NOT T_EKPO_TEMP[] IS INITIAL .
SELECT MATNR MAKTX
INTO TABLE T_MAKT
FROM MAKT
FOR ALL ENTRIES IN T_EKPO_TEMP
WHERE MATRN = T_EKPO_TEMP-MATNR
AND SPRAS = SY-LANGU.
ENDIF.
然后再通过Read T_MAKT 将料号描述塞入T_EKPO.
这个其实就是把数据库里面的数据都读到内表里面处理,因为不停的访问数据库的话,效率很低,直接一次把所有需要的数据都读到内表里通过内存处理,效率会高几倍到十几倍。简单的举个例子,就是比如你的内表里有物料号,你现在需要去数据库表中取物料描述,如果你循环内表,然后在循环中用select去数据库中查找物料描述,这样就会不停的访问数据库。如果有几千条物料,就会访问数据库几千次。但是我们也不可能一次把几百万甚至几千万的物料描述一次全部从数据库里读到内表中,这就需要我们通过for all entries in根据内表中的物料号作为条件,在数据库中一次把我们需要的物料描述取出来。至于你说的inner join是可以用的,不过效率很低,不推荐这样用。你刚学可能对效率的感觉还很差,后面会慢慢明白的。
INNER/LEFT/RIGHT/OUTTER JOIN是在访问DB的时候适用的!而当你需要将一内表中的某个字段的值作为选择条件来使用的话,就要用到FOR ALL ENTRIES命令!语法为:
SELCT (FIELD NAME)
INTO TABLE (INNER TABLE NAME)
FROM (DB TABLE NAME)
FOR ALL ENTRIES IN IT_DATA
WHERE (CONDITION FIELD NAME) = IT_DATA-(FIELD NAME).
(IT_DATA即为选择条件的值所在的内表)
注意:在用FOR ALL ENTRIES时应注意:
1.IT_DATA不可为空,如为空,系统将忽视该条件,导致该选择条件无效
2.在抽取字段中应将DB中所有主键写全,否则系统会将符合条件的所有记录以抽取字段做DISTINCT,导致抽取数据缺失
3.最好将IT_DATA中选择用字段做排序后删除重复记录,这样会提高性能!
希望能帮到你!
forr all entries in:查询条件在内表中,无需使用循环内表loop at itab, Select * from table ,减少与数据库交互,提高数据读取速度。
inner join:普通的透明表可以用,簇表不可以使用。