从内部表中提取唯一值

时间:2015-09-30 09:52:01

标签: sap abap

从内部表的一列或多列中提取唯一值的最有效方法是什么?

3 个答案:

答案 0 :(得分:6)

在ABAP 7.40发布SP08之前,从内部表或itab中提取唯一值的最有效方法如下:

LOOP AT lt_itab ASSIGNING <ls_itab>.
    APPEND <ls_itab>-value TO lt_values.
ENDLOOP.
SORT lt_values.
DELETE ADJACENT DUPLICATES FROM lt_values.

在将其添加到内部表之前检查给定<ls_itab>-value的存在是另一种保证唯一性的方法,但在插入标准表时可能会计算成本更高 。对于已排序或散列的目标表,请使用:

LOOP AT lt_itab ASSIGNING <ls_itab>.
    READ TABLE lt_sorted_values WITH KEY table_line = <ls_itab>-value BINARY SEARCH.
    IF sy-subrc <> 0.
        APPEND <ls_itab>-value TO lt_sorted_values.
    ENDIF.
ENDLOOP.

请注意,使用第一种方法但将值插入虚拟表后跟APPEND LINES OF lt_dummy INTO lt_sorted_values 可能会更快,但中间表的大小可能会混淆。

从ABAP 7.40 Support Package 08开始, GROUP BY循环提供了一种更好的方法来提取唯一值。正如名称所示,这些功能与SQL GROUP BY类似。例如,以下代码将从内部表中提取唯一的项目编号:

LOOP AT lt_project_data ASSIGNING FIELD-SYMBOL(<ls_grp_proj>)
    GROUP BY ( project = <ls_grp_proj>-proj_number ) ASCENDING
    WITHOUT MEMBERS
    ASSIGNING FIELD-SYMBOL(<ls_grp_unique_proj>).
        APPEND <ls_grp_unique_proj>-project TO lt_unique_projects.
ENDLOOP.

可以扩展相同的逻辑以检索唯一对,例如EKPO表的复合主键,EBELN(&#34;采购文档&#34;,po_nr )和EBELP(&#34;采购文件的项目编号&#34;,po_item):

LOOP AT lt_purchasing_document_items ASSIGNING FIELD-SYMBOL(<ls_grp_po>)
    GROUP BY ( number = <ls_grp_po>-po_nr
               item   = <ls_grp_po>-po_item ) ASCENDING
    WITHOUT MEMBERS
    ASSIGNING FIELD-SYMBOL(<ls_grp_po_item>).
        APPEND VALUE #( ebeln = <ls_grp_po_item>-number
                        ebelp = <ls_grp_po_item>-item ) TO lt_unique_po_items.
ENDLOOP.

新的ABAP 7.40版本的SAP设计人员之一Horst Keller表示the performance of GROUP BY loops is likely to be the same作为这些LOOP的手动实现。根据如何(有效)实现这样的自定义循环,它甚至可能更快。请注意,对于GROUP BY循环不可用的系统,这些方法将比上面给出的两种方法更快。

请注意,在大多数情况下,查询数据库以返回DISTINCT值将会快得多并且在性能方面这样做会破坏任何使用内部表格的ABAP代码, HANA系统上的尤其

答案 1 :(得分:6)

如果你有 7.40 SP08 或更高版本,你只需使用内联语法填充目标表(不需要LOOP GROUP BY):

DATA: it_unique TYPE STANDARD TABLE OF fieldtype.
it_unique = VALUE #(
  FOR GROUPS value OF <line> IN it_itab
  GROUP BY <line>-field WITHOUT MEMBERS ( value ) ).

这适用于任何类型的目标表。

对于旧版本,请使用:

DATA: it_unique TYPE HASHED TABLE OF fieldtype WITH UNIQUE KEY table_line.
LOOP AT it_itab ASSIGNING <line>.
  INSERT <line>-field INTO TABLE lt_unique.
ENDLOOP.

以上工作也适用于排序表。虽然我不建议将排序表用于此目的,除非您确定结果中只有几行。

sy-subrc的非零INSERT被忽略。无需进行两次密钥查找(一次用于存在检查,一次用于插入)。

如果目标必须是 STANDARD TABLE 并且您有旧ABAP堆栈,您可以选择使用

DATA: it_unique TYPE STANDARD TABLE OF fieldtype.
LOOP AT it_itab ASSIGNING <line>.
  READ TABLE lt_unique WITH TABLE KEY table_line = <line>-field
    TRANSPORTING NO FIELDS BINARY SEARCH.
  INSERT <line>-field INTO lt_unique INDEX sy-tabix.
ENDLOOP.

这提供了与排序表相同的行为,但具有标准表。 这是否比SORT / DELETE ADJACENT DUPLICATES更有效取决于itab中重复条目的数量。存在的重复条目越多,上述解决方案就越快,因为它避免了对目标表的不必要的附加。但另一方面,追加比插入更快。

答案 2 :(得分:3)

这个怎么样?

lt_unique[] = lt_itab[].
SORT lt_unique[] BY field1 field2 field3...
DELETE ADJACENT DUPLICATES FROM lt_values COMPARING field1 field2 field3...