SAP 查询数据库进行表连接

597 阅读3分钟

介绍

在 ABAP 开发中,经常需要进行表连接,SAP 的 SQL 也提供了 left joinright joinouter joininner join 等等。

语法:

... [(] { data_source [AS tabalias]}|join
          {[INNER] JOIN}|{LEFT|RIGHT [OUTER [MANY TO ONE]] JOIN}|{CROSS JOIN}
             { data_source [AS tabalias]}|join [ON sql_cond] [)] ... .

在一个连接表达式中,将查询结果集中的两个或多个数据源的列连接起来。一个连接表达式将左边的数据与右边的数据连接起来,使用:

  • INNER JOIN
  • LEFT | RIGHT [OUTER] JOIN
  • CROSS JOIN

在 View 中,我们需要连接两个表; 这两个表可以有或不能有共同的键。 在视图的情况下,我们在合并记录的基础上给出连接条件(例如 table1-field1 = table2-field1)。

1. 无条件 join

Views-002 (1).webp

试图输出两个表中结合的数据,使用 INNER JOIN:

SELECT * FROM table1 INNER JOIN table2 ON table1.name = table2.name AND table1.date = '20230421'.

2. 有条件 join

加上字段条件的表连接,比如此时的 table1-field1=table2-fieldA会删除不符合条件的行记录。如图所示:

Views-003.webp

此时,通过加入条件重复的数据也会被删除:

Views-004.webp

最后变成这样的视图:

Views-005.webp

3. Left Join

一个连接操作通过使用特定的条件将两个表格组合在一起。您可以选择内部连接和左外连接。

内部连接将来自两个表格的数据合并,如果满足所有指定的条件。如果一个或多个条件不满足,则不会在结果集中创建数据记录。

左外连接将左表格中的所有值与满足条件的右表格中的值组合在一起。左表格中的所有值都包含在结果表格中,即使它们不满足条件也是如此。如果左表格返回一个表格行并且右表格返回多个匹配行,则左表格的值将为右表格中的每一行重复。

SELECT * FROM A 
   LEFT JOIN B ON A.key = B.key 
   WHERE B.key IS NULL

4. Right Join

SELECT * FROM A 
   RIGHT JOIN B ON A.key = B.key
   WHERE A.key IS NULL

JOIN 表达式绕过缓冲。 我们可以使用 FOR ALL ENTRIES 来访问表缓冲区。

查询报表示例

REPORT zprod.
TABLES: mara,marc.

TYPES:
  BEGIN OF production_order_line_t,
    material_number                TYPE mara-matnr,
    plant                          TYPE marc-werks,
    material_description           TYPE makt-maktx,
    planned_order_number           TYPE plaf-plnum,
    total_planned_order_quantity   TYPE plaf-gsmng,
    planned_order_finish_date      TYPE plaf-pedtr,
    production_order_number        TYPE afpo-aufnr,
    production_order_sched_finish  TYPE afpo-dglts,
    production_order_item_quantity TYPE afpo-psmng,
    prod_order_unit_of_measure     TYPE afpo-meins,
    movement_type                  TYPE mseg-bwart,
    document_quantity              TYPE mseg-menge,
    document_unit_of_measure       TYPE mseg-meins,
    document_posting_date          TYPE mseg-budat_mkpf,
  END OF production_order_line_t.

DATA: production_orders TYPE STANDARD TABLE OF production_order_line_t.

SELECTION-SCREEN BEGIN OF BLOCK a.
  SELECT-OPTIONS s_matnr FOR mara-matnr.
  SELECT-OPTIONS s_werks FOR marc-werks.
SELECTION-SCREEN END OF BLOCK a.

START-OF-SELECTION.
  SELECT
    FROM mara
    JOIN marc
      ON marc~matnr = mara~matnr
    LEFT OUTER JOIN makt
      ON makt~matnr = mara~matnr
     AND makt~spras = @sy-langu
    JOIN plaf
      ON plaf~matnr = mara~matnr
     AND plaf~plwrk = marc~werks
    JOIN afpo
      ON afpo~matnr = marc~matnr
     AND afpo~pwerk = marc~werks
    JOIN mseg
      ON mseg~matnr = marc~matnr
     AND mseg~werks = marc~werks
     AND mseg~bwart = '101'
  FIELDS mara~matnr, marc~werks, makt~maktx,
         plaf~plnum, plaf~gsmng, plaf~pedtr,
         afpo~aufnr, afpo~dglts, afpo~psmng, afpo~meins,
         mseg~bwart, mseg~menge, mseg~meins, mseg~budat_mkpf
    WHERE mara~matnr IN @s_matnr
      AND marc~werks IN @s_werks
    INTO TABLE @production_orders.

END-OF-SELECTION.

  SORT production_orders BY material_number planned_order_number ASCENDING.
  DELETE ADJACENT DUPLICATES FROM production_orders COMPARING planned_order_number.

  DATA alv_table TYPE REF TO cl_salv_table.
  TRY.
      CALL METHOD cl_salv_table=>factory
        EXPORTING
          list_display = if_salv_c_bool_sap=>false
        IMPORTING
          r_salv_table = alv_table
        CHANGING
          t_table      = production_orders.
      ##NO_HANDLER.
    CATCH cx_salv_msg .
  ENDTRY.
  CALL METHOD alv_table->display( ).

参考链接: