[英]Grouping + aggregation of itab with table comprehensions
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, ie 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
The result table to be populated要填充的结果表
VENDOR DELIVERY DATE
10 00055 01/01/2019
20 00120 11/22/2019
40 00200 04/10/2019
I implemented this in a following way, via DESCENDING, which I find very ugly我通过以下方式实现了这一点,通过 DESCENDING,我觉得这很丑陋
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?有没有更优雅的方法来做到这一点?
I also tried REDUCE
我也试过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 ) ) ).
but REDUCE
selects max date from the whole table and it selects only flat structure , which is not what I want.但是REDUCE
从整个表中选择 max date 并且它只选择flat structure ,这不是我想要的。 However, in ABAP examples I saw samples where table-to-table reductions are also possible.但是,在 ABAP 示例中,我看到了也可以进行表到表缩减的示例。 Am I wrong?我错了吗?
Another thing I tried is finding uniques with WITHOUT MEMBERS
but this syntax doesn't work:我尝试的另一件事是使用WITHOUT MEMBERS
查找唯一值,但此语法不起作用:
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->* ) ).
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.如您所见,我使用数据参考 ( aux_ref_s_vend2
) 以获得更好的性能,以指向具有最新日期的行。 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: I could not test it because the question does not provide a MCVE . PS:我无法测试它,因为问题没有提供MCVE 。
Here is another solution if you really want to use REDUCE in the primary constructor expression (but it's not needed):如果您真的想在主构造函数表达式中使用 REDUCE,这是另一种解决方案(但不需要):
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->* ) ) ).
what do you mean by elegant solution?优雅的解决方案是什么意思? Using GROUP or REDUCE with the "new" abap syntax is not making it elegant in any way, at least for me...将 GROUP 或 REDUCE 与“新的”abap 语法一起使用并没有使它变得优雅,至少对我而言......
For me, coding that is easily understandable for everyone is elegant:对我来说,每个人都容易理解的编码是优雅的:
SORT itab BY vendor date DESCENDING.
DELETE ADJACENT DUPLICATES from itab COMPARING vendor.
Or if the example is more complex, a simple LOOP AT
with IF
or AT
in it APPENDING
aggregated lines to a new itab, will also solve it.或者,如果示例更复杂,一个简单的带有IF
或AT
LOOP AT
将聚合行APPENDING
到新的 itab,也可以解决它。 Example here . 示例在这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.