使用表推导式对 itab 进行分组 + 聚合 [英] Grouping + aggregation of itab with table comprehensions

查看:45
本文介绍了使用表推导式对 itab 进行分组 + 聚合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相当典型的任务,但我坚持以漂亮的方式完成它.

Rather typical task but I'm stuck on doing it in a beautiful way.

例如,我需要找到每个供应商的最后一次发货,即找到每个供应商的最大日期的交货

For example, I need to find the last shipment for each vendor, i.e. to find delivery with the max date for the each vendor

VENDOR     DELIVERY   DATE
10          00055    01/01/2019
20          00070    01/19/2019
20          00088    01/20/2019
20          00120    11/22/2019
40          00150    04/01/2019
40          00200    04/10/2019

要填充的结果表

VENDOR     DELIVERY   DATE
10          00055    01/01/2019
20          00120    11/22/2019
40          00200    04/10/2019

我通过以下方式实现了这个,通过 DESCENDING,我觉得这很丑

I implemented this in a following way, via DESCENDING, which I find very ugly

LOOP AT itab ASSIGNING <wa> GROUP BY ( ven_no = <wa>-ven_no ) REFERENCE INTO DATA(vendor).
  LOOP AT GROUP vendor ASSIGNING <ven> GROUP BY ( date = <vendor>-date ) DESCENDING.
    CHECK NOT line_exists( it_vend_max[ ven_no = <ven>-ven_no ] ).
    it_vend_max = VALUE #( BASE it_vend_max ( <ven> ) ).
  ENDLOOP.
ENDLOOP.

有没有更优雅的方法来做到这一点?

Is there more elegant way to do this?

我也试过REDUCE

result = REDUCE #( vend_line = value ty_s_vend()
                   MEMBERS = VALUE ty_t_vend( )
                   FOR GROUPS <group_key> OF <wa> IN itab
                   GROUP BY ( key = <wa>-ven_no count = GROUP SIZE
                   ASCENDING
         NEXT vend_line = VALUE #(
              ven_no = <wa>-ven_no

              date  = REDUCE i( INIT max = 0
                                FOR m IN GROUP <group_key>
                                NEXT max = nmax( val1 = m-date
                                                 val2 = <wa>-date ) )
              deliv_no  = <wa>-deliv_no
         MEMBERS = VALUE ty_s_vend( FOR m IN GROUP <group_key> ( m ) ) ).

但是REDUCE 从整个表中选择最大日期并且它只选择扁平结构,这不是我想要的.但是,在 ABAP 示例中,我看到了也可以进行表到表缩减的示例.我错了吗?

but REDUCE selects max date from the whole table and it selects only flat structure, which is not what I want. However, in ABAP examples I saw samples where table-to-table reductions are also possible. Am I wrong?

我尝试的另一件事是使用 WITHOUT MEMBERS 查找唯一值,但此语法不起作用:

Another thing I tried is finding uniques with WITHOUT MEMBERS but this syntax doesn't work:

it_vend_max = VALUE ty_t_vend( FOR GROUPS value OF <line> IN itab 
                               GROUP BY ( <line>-ven_no <line>-ship_no ) 
                               WITHOUT MEMBERS ( lifnr = value 
                                                 date = nmax( val1 = <line>-date 
                                                              val2 = value-date ) ) ).

对这里有什么问题的任何建议或自己的优雅解决方案表示赞赏.

Any suggestion of what is wrong here or own elegant solution is appreciated.

推荐答案

如果不是太复杂,我认为最好使用一个构造表达式,这表明该表达式的目标是初始化一个变量而不是其他.

If not too complex, I think it's best to use one construction expression, which shows that the goal of the expression is to initialize one variable and nothing else.

我能做到的最好的表现和最短的可能,但我不能让它优雅:

The best I could do to be the most performing and the shortest possible, but I can't make it elegant:

TYPES ty_ref_s_vend TYPE REF TO ty_s_vend.

result = VALUE ty_t_vend(
    FOR GROUPS <group_key> OF <wa> IN itab
    GROUP BY ( ven_no = <wa>-ven_no ) ASCENDING
    LET max2 = REDUCE #(
        INIT max TYPE ty_ref_s_vend
        FOR <m> IN GROUP <group_key>
        NEXT max = COND #( WHEN max IS NOT BOUND
                             OR <m>-date > max->*-date
                           THEN REF #( <m> ) ELSE max ) )
    IN ( max2->* ) ).

如您所见,我使用数据引用 (aux_ref_s_vend2) 来获得更好的性能,以指向具有最新日期的行.理论上它比复制整行的字节更快,但可读性较差.如果你没有大表,使用辅助数据引用和辅助数据对象不会有太大区别.

As you can see I use a data reference (aux_ref_s_vend2) for a better performance, to point to the line which has the most recent date. It's theoretically faster than copying the bytes of the whole line, but it's less readable. If you don't have a huge table, there won't be a big difference between using an auxiliary data reference or an auxiliary data object.

PS:我无法测试它,因为问题没有提供 MCVE.

PS: I could not test it because the question does not provide a MCVE.

如果您真的想在主构造函数表达式中使用 REDUCE,这是另一种解决方案(但不是必需的):

Here is another solution if you really want to use REDUCE in the primary constructor expression (but it's not needed):

result = REDUCE ty_t_vend(
    INIT vend_lines TYPE ty_t_vend
    FOR GROUPS <group_key> OF <wa> IN itab
    GROUP BY ( ven_no = <wa>-ven_no ) ASCENDING
    NEXT vend_lines = VALUE #(
        LET max2 = REDUCE ty_ref_s_vend(
            INIT max TYPE ty_ref_s_vend
            FOR <m> IN GROUP <group_key>
            NEXT max = COND #( WHEN max IS NOT BOUND
                                 OR <m>-date > max->*-date
                               THEN REF #( <m> ) ELSE max ) )
        IN BASE vend_lines
        ( max2->* ) ) ).

这篇关于使用表推导式对 itab 进行分组 + 聚合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆