From release 7.40 and onward, this can be accomplished by combining grouping in internal tables (FOR GROUPS
) with REDUCE
for calculating the sum of each group.
First a couple declarations:
TYPES:
BEGIN OF data_struct,
category TYPE c LENGTH 3,
amount TYPE i,
END OF data_struct,
data_tab TYPE STANDARD TABLE OF data_struct WITH EMPTY KEY.
DATA(input) = VALUE data_tab(
( Category = 'AAA' Amount = 10 )
( Category = 'AAA' Amount = 20 )
( Category = 'BBB' Amount = 30 )
( Category = 'CCC' Amount = 40 )
( Category = 'CCC' Amount = 50 )
( Category = 'CCC' Amount = 60 )
).
And here the solution:
DATA(output) = VALUE data_tab(
FOR GROUPS group OF input_line IN input
GROUP BY ( category = input_line-category )
( category = group-category
amount = REDUCE #(
INIT subtotal = 0
FOR group_line IN GROUP group
NEXT subtotal = subtotal + group_line-amount
)
)
).
Now what exactly happens here?
The data for the internal table output
is generated by FOR GROUPS
. The FOR GROUPS
table expression consists of three parts: The declaration of the group, the grouping criteria and the results.
First about the declarative part: GROUPS group OF input_line IN input
. This defines that there is a group called "group", that its source is the internal table "input" and that we refer to each line of that source table as "input_line".
Next the grouping criteria: GROUP BY ( category = input_line-category )
. This means that each group is identified by a key with a single field "category" and that we want to group all lines where the field "category" is identical.
And now for the result part:
( category = group-category
amount = REDUCE #(
INIT subtotal = 0
FOR group_line IN GROUP group
NEXT subtotal = subtotal + group_line-amount
)
)
This defines how each group is supposed to be represented in the output set. The first field "category" is simple - just put in the value of "category" of the group called "group".
The second field "amount" is a bit more complicated, because its value is calculated by a REDUCE
. The purpose of the REDUCE construction expression is to take many values and turn them into one value. It does this by doing the following things:
- Declare and initialize a variable:
INIT subtotal = 0
- Do a loop over an internal table or the lines of a group in an outer
FOR GROUPS
. In this case the latter: FOR group_line IN GROUP group
- Do the same code snippet with each line of that input, changing the variable. In this case by adding its amount to the subtotal:
NEXT subtotal = subtotal + group_line-amount
- Return the final value of the variable declared in step 1.
Result from debugger:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…