在ABAP中用for all entries in代替inner join

标签:ABAP

取数据一般都会用到多个表,inner join是非常常用的操作,但因为比较耗数据库资源,所以很多时间不推荐。

大家也知道,SAP这东西,应用服务器可以扩展为多个,但数据库服务器只有一个,所以必须少消耗DB资源。

据boss说,一般多对多或关联很多表(例如3个以上)时就不用inner join(前者是因为难搞清关系,不太清晰),应改成for all entries in。

header-item或多对一关系就可以inner join(即另一张表的where语句上所有的key都唯一确定了)。

下面给个例子(老师写的代码,稍微改动了一下):
report  ztest_jion.

initialization.

  tables : vbak.

  types : begin of ty_vbak,
    vbeln type vbeln_va,
    erdat type erdat,
    kunnr type kunag,
  end of ty_vbak.

  types : begin of ty_vbap,
    vbeln type vbeln_va,
    posnr type posnr,
    matnr type matnr,
  end of ty_vbap.

  types : begin of ty_fin,
    vbeln type vbeln_va,
    erdat type erdat,
    kunnr type kunag,
    posnr type posnr,
    matnr type matnr,
  end of ty_fin.

  data : t_vbak type standard table of ty_vbak,
  t_vbap type standard table of ty_vbap,
  t_fin_all type standard table of ty_fin,
  t_fin_join type standard table of ty_fin,
  w_vbak type ty_vbak ,
  w_vbap type ty_vbap ,
  w_fin type ty_fin.

  select-options : s_vbeln for vbak-vbeln.

start-of-selection.
  select
  vbak~vbeln
  vbak~erdat
  vbak~kunnr
  vbap~posnr
  vbap~matnr
  into table t_fin_join
  from vbak inner join vbap
  on vbak~vbeln = vbap~vbeln
  where vbak~vbeln in s_vbeln.
  if sy-subrc <> 0.
    write : 'No data.'.
    exit.
  endif.

  select
  vbeln
  erdat
  kunnr
  from vbak
  into table t_vbak
  where vbeln in s_vbeln.
  if t_vbak[] is not initial.
    select
    vbeln
    posnr
    matnr
    from vbap
    into table t_vbap
    for all entries in t_vbak
    where vbeln = t_vbak-vbeln.
  endif.

end-of-selection.

  write : /  'Inner jion:',
          /  'Sales Document',
          20 'Create Date',
          40 'Sold-to party',
          60 'Sales Document Item',
          80 'Material Number'.
  sort t_fin_join.
  loop at t_fin_join into w_fin.
    write : /   w_fin-vbeln,
            20  w_fin-erdat,
            40  w_fin-kunnr,
            60  w_fin-posnr,
            80  w_fin-matnr.
  endloop.

  skip.

  loop at t_vbap into w_vbap.
    w_fin-vbeln = w_vbap-vbeln.
    w_fin-posnr = w_vbap-posnr.
    w_fin-matnr = w_vbap-matnr.
    read table t_vbak into w_vbak with key
    vbeln = w_vbap-vbeln.
    if sy-subrc = 0.
      w_fin-erdat = w_vbak-erdat.
      w_fin-kunnr = w_vbak-kunnr.
    endif.
    append w_fin to t_fin_all.
    clear w_fin.
  endloop.

  sort t_fin_all.
  write : /  'For all entries in:',
          /  'Sales Document',
          20 'Create Date',
          40 'Sold-to party',
          60 'Sales Document Item',
          80 'Material Number'.
  loop at t_fin_all into w_fin.
    write : /   w_fin-vbeln,
            20  w_fin-erdat,
            40  w_fin-kunnr,
            60  w_fin-posnr,
            80  w_fin-matnr.
  endloop.
1个inner join变成了3段代码,看上去貌似很不值得,但还是分析下代码吧。

第一个是将vbak和vbap这2个表在vbeln相等的条件下进行inner join。

第二个则先从vbak中提取数据放入t_vbak。
再从vbap中提取所有vbeln = t_vbak-vbeln的数据放入t_vbap。
最后再遍历t_vbap,并从t_vbak读取相应数据,构造一个t_fin_all。
至此,t_fin_join和t_fin_all的数据就相同了(只是顺序不同,排序下就一样了)。

1条评论 你不来一发么↓ 顺序排列 倒序排列

    向下滚动可载入更多评论,或者点这里禁止自动加载

    想说点什么呢?