Abap 从itab获取其他字段中每个不同值的最高值

Abap 从itab获取其他字段中每个不同值的最高值,abap,Abap,我需要从内部表中为每个不同的VKONT获取具有最高EXBEL寄存器的行 如果同一VKONT值的结果表在源表中有多行具有相同的最高EXBEL值,则该结果表可能包含多行 实际来源表: SPARTE VKONT EXBEL 05 800000008422 1NSN150900000058 L2 800000008422 1NSN150900000058 05 800000008422 1NSN150900000037 L2 8000000

我需要从内部表中为每个不同的VKONT获取具有最高EXBEL寄存器的行

如果同一VKONT值的结果表在源表中有多行具有相同的最高EXBEL值,则该结果表可能包含多行

实际来源表:

SPARTE  VKONT         EXBEL
05      800000008422  1NSN150900000058
L2      800000008422  1NSN150900000058
05      800000008422  1NSN150900000037
L2      800000008422  1NSN150900000037
05      800000008422  1NSN150900000013
L2      800000008422  1NSN150900000013
05      800000008415  1HSN151200000009
S1      800000008415  1HSN151200000009
05      800000008415  1HSN151200000008
S1      800000008415  1HSN151200000008
L1      800000008422  1NSN150900000050
L1      800000008422  1NSN150900000029
L1      800000008422  1NSN150900000023
05      800000008415  1HSN151200000012
S1      800000008415  1HSN151200000012
05      800000008422  1NSN150900000058
L2      800000008422  1NSN150900000058
05      800000008415  1HSN151200000009
S1      800000008415  1HSN151200000009
预期结果表:

SPARTE  VKONT         EXBEL
05      800000008422  1NSN150900000058
L2      800000008422  1NSN150900000058
05      800000008415  1HSN151200000012
S1      800000008415  1HSN151200000012
我尝试了不同的解决方案,但没有成功

任何帮助都将不胜感激

劳尔

您可以使用排序,然后删除相邻的重复项,因为后者将删除某些行组中的所有行,但组中的第一行除外

SORT itab BY vkont exbel DESCENDING. " Group by VKONT and put highest EXBEL in the group first
DELETE ADJACENT DUPLICATES FROM itab COMPARING VKONT.
如果您需要保持原始itab的完整性,可能有更有效的方法。

您可以使用排序,然后删除相邻的重复项,因为后者将删除某些行组中的所有行,但组中的第一行除外

SORT itab BY vkont exbel DESCENDING. " Group by VKONT and put highest EXBEL in the group first
DELETE ADJACENT DUPLICATES FROM itab COMPARING VKONT.

如果您需要保持原始itab的完整性,可能会有更有效的方法。

从7.52开始,您可以在内部表上使用。示例代码如下

TYPES:
BEGIN OF ty_s_value,
   sparte TYPE char2,
   vkont  TYPE char12,
   exbel  TYPE char16,
END OF ty_s_value.

TYPES:
ty_t_value TYPE STANDARD TABLE OF ty_s_value .

DATA:
  lt_value TYPE ty_t_value.

lt_value = VALUE #(
                    ( sparte = '05' vkont = '800008422' exbel = '0000000000000001')
                    ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000002')
                    ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000004')
                    ( sparte = '05' vkont = '800008423' exbel = '0000000000000003')
                    ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000002')
                    ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000005')
                 ).

SELECT FROM @lt_value AS a FIELDS a~sparte, a~vkont, MAX( a~exbel ) AS exbel 
   GROUP BY a~sparte, a~vkont
   ORDER BY a~sparte, a~vkont INTO TABLE @DATA(result).

从7.52开始,您可以在内部表上进行操作。示例代码如下

TYPES:
BEGIN OF ty_s_value,
   sparte TYPE char2,
   vkont  TYPE char12,
   exbel  TYPE char16,
END OF ty_s_value.

TYPES:
ty_t_value TYPE STANDARD TABLE OF ty_s_value .

DATA:
  lt_value TYPE ty_t_value.

lt_value = VALUE #(
                    ( sparte = '05' vkont = '800008422' exbel = '0000000000000001')
                    ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000002')
                    ( sparte = 'l2' vkont = '800008422' exbel = '0000000000000004')
                    ( sparte = '05' vkont = '800008423' exbel = '0000000000000003')
                    ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000002')
                    ( sparte = 'l2' vkont = '800008423' exbel = '0000000000000005')
                 ).

SELECT FROM @lt_value AS a FIELDS a~sparte, a~vkont, MAX( a~exbel ) AS exbel 
   GROUP BY a~sparte, a~vkont
   ORDER BY a~sparte, a~vkont INTO TABLE @DATA(result).
聚集到哈希表 这适用于当前支持的任何版本,比排序+删除相邻重复项快2倍,并保持原始表不变

FIELD-SYMBOLS: <fs_itab> LIKE LINE OF lt_original.

DATA: ls_itab   LIKE LINE OF lt_original,
      lt_hashed TYPE HASHED TABLE OF itab WITH UNIQUE KEY vkont.

LOOP AT lt_original INTO ls_itab.
  READ TABLE lt_hashed ASSIGNING <fs_itab>
      WITH KEY vkont = ls_itab-vkont.
  IF sy-subrc = 0.
    IF ls_itab-exbel > <fs_itab>-exbel.
      <fs_itab>-exbel  = ls_itab-exbel.
      <fs_itab>-sparte = ls_itab-sparte.  "remove this if not needed"
    ENDIF.
  ELSE.
    INSERT ls_itab INTO TABLE lt_hashed.
  ENDIF.
ENDLOOP.
1 SORT+DAD具有On*logn的速度缩放,而这具有On

聚集到哈希表 这适用于当前支持的任何版本,比排序+删除相邻重复项快2倍,并保持原始表不变

FIELD-SYMBOLS: <fs_itab> LIKE LINE OF lt_original.

DATA: ls_itab   LIKE LINE OF lt_original,
      lt_hashed TYPE HASHED TABLE OF itab WITH UNIQUE KEY vkont.

LOOP AT lt_original INTO ls_itab.
  READ TABLE lt_hashed ASSIGNING <fs_itab>
      WITH KEY vkont = ls_itab-vkont.
  IF sy-subrc = 0.
    IF ls_itab-exbel > <fs_itab>-exbel.
      <fs_itab>-exbel  = ls_itab-exbel.
      <fs_itab>-sparte = ls_itab-sparte.  "remove this if not needed"
    ENDIF.
  ELSE.
    INSERT ls_itab INTO TABLE lt_hashed.
  ENDIF.
ENDLOOP.

1 SORT+DAD的速度缩放为On*logn,而这是On

这里是REDUCE解决方案,REDUCE操作符从ABAP 7.40 SP08开始就可用

TYPES: BEGIN OF ty_s_value,
        sparte TYPE char2,
        vkont  TYPE char12,
        exbel  TYPE char16,
       END OF ty_s_value.
TYPES: ty_t_value TYPE STANDARD TABLE OF ty_s_value WITH EMPTY KEY.

DATA(lt_tab) = 
VALUE ty_t_value( 
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000058')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000058')
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000037')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000037')
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000013')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000013')
                 ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000009')
                 ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000009')
                 ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000008')
                 ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000008')
                 ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000050')
                 ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000029')
                ...
                ).

DATA(lt_result) = 
VALUE ty_t_value( FOR GROUPS <group_key> OF <wa> IN lt_tab 
                  GROUP BY ( sparte = <wa>-sparte vkont = <wa>-vkont )
                  LET max2 = 
                  REDUCE #( INIT max = 
                            VALUE ty_s_value( )
                            FOR <m> IN GROUP <group_key>
                            NEXT max = COND #( WHEN <m>-exbel > max-exbel THEN <m> ELSE max ) )
                  IN ( max2 ) ).

顺便说一句,您的预期结果集缺少L1行,我假设在您的选择中,您不仅尊重VKONT,而且也尊重SPARTE。

这里是REDUCE解决方案,REDUCE运算符自ABAP 7.40 SP08起可用

TYPES: BEGIN OF ty_s_value,
        sparte TYPE char2,
        vkont  TYPE char12,
        exbel  TYPE char16,
       END OF ty_s_value.
TYPES: ty_t_value TYPE STANDARD TABLE OF ty_s_value WITH EMPTY KEY.

DATA(lt_tab) = 
VALUE ty_t_value( 
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000058')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000058')
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000037')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000037')
                 ( sparte = '05' vkont = '800000008422' exbel = '1NSN150900000013')
                 ( sparte = 'L2' vkont = '800000008422' exbel = '1NSN150900000013')
                 ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000009')
                 ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000009')
                 ( sparte = '05' vkont = '800000008415' exbel = '1HSN151200000008')
                 ( sparte = 'S1' vkont = '800000008415' exbel = '1HSN151200000008')
                 ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000050')
                 ( sparte = 'L1' vkont = '800000008422' exbel = '1NSN150900000029')
                ...
                ).

DATA(lt_result) = 
VALUE ty_t_value( FOR GROUPS <group_key> OF <wa> IN lt_tab 
                  GROUP BY ( sparte = <wa>-sparte vkont = <wa>-vkont )
                  LET max2 = 
                  REDUCE #( INIT max = 
                            VALUE ty_s_value( )
                            FOR <m> IN GROUP <group_key>
                            NEXT max = COND #( WHEN <m>-exbel > max-exbel THEN <m> ELSE max ) )
                  IN ( max2 ) ).


顺便说一句,您的预期结果集缺少L1行,我假设在您的选择中,您不仅尊重VKONT,而且也尊重SPARTE。

请编辑您的问题以澄清您预期的值。此外,请附上您尝试过的代码相关部分,并解释您到目前为止得到了什么。请看页面。我已经编辑了您的问题以澄清它,请确认它是否与您的问题对应。如果没有,请编辑它。谢谢,谢谢桑德拉。是的,解释得很好。请编辑您的问题以澄清您期望的值。此外,请附上您尝试过的代码相关部分,并解释您到目前为止得到了什么。请看页面。我已经编辑了您的问题以澄清它,请确认它是否与您的问题对应。如果没有,请编辑它。谢谢,谢谢桑德拉。是的,解释得很好。谢谢你的回答,但是用这段代码我只得到了每个vkont的一个寄存器,而不是那个vkont的所有具有相同最高exbel的寄存器。谢谢你的回答,但是用这段代码我只得到了每个vkont的一个寄存器,而不是那个vkont的所有具有相同最高exbel的寄存器。哇,这种方法感觉非常简单和直观。遗憾的是,我使用的是740 SAP版本。它不仅是7.52,还取决于数据库及其版本,适用于HANA 2.0,但不适用于Sybase ASE 16.0;它可以在运行时使用类CL_ABAP_DBFEATURES的USE_FEATURES方法进行检查。性能基准测试很有意思,我担心SELECT与ABAP语句相比可能会非常慢。@SandraRossi根据数据库的定义,只有当您的SELECT实际上也使用了数据库(如在联接中)时,DB才起作用。如果不使用它,为什么和如何重要?@András我不知道为什么重要,但在我的7.52 ASE系统上,上面的代码有一个CX_SY_SQL_UNSUPPORTED_功能不受支持的数据库扩展。所以,在所有数据库系统上,如果需要将内部表中的数据传递到数据库,问题是什么时候需要传递?@SandraRossi我猜当您使用数据库表和内部表进行连接时,这种方法感觉非常简单和直观。遗憾的是,我使用的是740 SAP版本。它不仅是7.52,还取决于数据库及其版本,适用于HANA 2.0,但不适用于Sybase ASE 16.0;它可以在运行时使用类CL_ABAP_DBFEATURES的USE_FEATURES方法进行检查。性能基准测试很有意思,我担心SELECT与ABAP语句相比可能会非常慢。@SandraRossi根据数据库的定义,只有当您的SELECT实际上也使用了数据库(如在联接中)时,DB才起作用。如果不使用它,为什么和如何重要?@András我不知道为什么重要,但在我的7.52 ASE系统上,上面的代码有一个CX_SY_SQL_UNSUPPORTED_功能不受支持的数据库扩展。因此,关于所有数据库系统,如果需要将内部表中的数据传递到数据库,问题是什么时候需要传递?@SandraRossi我猜当您使用数据库表和内部表进行连接时,为什么不使用语句COLLECT as I
它也使用一个内部哈希表?这将是一个更短的代码,并且可能更快,因为它是由内核完成的,没有ABAP字节码解释。COLLECT找不到MAX,只有SUM。因此,我们得到了错误的值fasterRemark for 1,为什么不使用语句COLLECT,因为它也使用内部哈希表?这将是一个更短的代码,并且可能更快,因为它是由内核完成的,没有ABAP字节码解释。COLLECT找不到MAX,只有SUM。所以我们更快地得到错误的值