This commit is contained in:
danrega
2024-06-24 14:35:20 +02:00
parent fbb576f8e4
commit 38ee7e932d
2 changed files with 363 additions and 215 deletions

View File

@@ -1835,46 +1835,195 @@ it_ref = NEW #( ).
## Grouping Internal Tables ## Grouping Internal Tables
To group internal tables, there are additions for both `LOOP AT` statements and constructor expressions. Find more information in the [Internal Tables: Grouping](11_Internal_Tables_Grouping.md) cheat sheet and a code snippet in the [Constructor Expressions](05_Constructor_Expressions.md#grouping-lines-in-internal-tables-with-valuereduce) cheat sheet. To group internal tables, there are additions for `LOOP AT` statements.
In the following example, an internal table is sorted and looped over using groups. The goal is to transfer a line from the original table to another table of the same type. This line has the highest value in component `b` among all lines that are grouped by component `a`. `LOOP AT ... GROUP BY`
- Groups the lines of internal tables based on a group key. Each group key represents a group, and the lines read are members of that group.
- Performs a loop across these groups.
- You can execute a nested loop across the members of each group using `LOOP AT GROUP` statements.
- The statements offer a variety of syntax options, such as the following. For more information, refer to the ABAP Keyword Documentation:
- `ASCENDING`/`DESCENDING` additions to specify the sort order in the group loop. You can also sort beforehand with `SORT` statements.
- `WITHOUT MEMBERS`: This creates groups (requiring group key binding) without assigning actual component values. Access to group lines is not possible. Use this when access is not necessary and you want to enhance read performance.
- Specifying the group key after `GROUP BY`
- This can be a single data object or multiple keys within parentheses, which define a structure with specific components.
- In simple cases, component values of the table line can be assigned to the group key or the components of the group key. However, expressions are also possible on the right side of the group key assignments.
- Storing group-specific information in structured group keys.
- `GROUP SIZE` to count group members, e.g., `gs = GROUP SIZE`.
- `GROUP INDEX` to index group members, e.g., `gi = GROUP INDEX`.
- You can choose component names (such as `gs` and `gi` in the previous example) freely.
- To use these components, you need a group key binding.
- Group key binding
- Can be specified at the end of the statement using `INTO` and a data object. You can also use data references (`REFERENCE INTO`) or field symbols (`ASSIGNING ...`).
- If specified, the current key's group key is assigned to the specified data object (data reference, or field symbol). You can then address the group in nested loops with `LOOP AT GROUP`.
- Note: You can access the read result (e.g., `dobj` in `LOOP AT itab INTO dobj`), but the component values are initial when the group key binding is specified. You can address the group and its component values in nested loops with `LOOP AT GROUP`.
- If you do not specify the group key binding, it defaults to a representative binding. In each loop pass, the first line of the current group is assigned to the target area. You can process this *representative* further in nested loops with `LOOP AT GROUP`. With representative binding, the `sy-tabix` value is set as if the loop was specified without grouping.
`LOOP AT GROUP`:
- Allows for a nested loop across group members.
- Only applicable with `LOOP ... GROUP BY` statements (provided `WITHOUT MEMBERS` isn't specified)
- After using `LOOP AT GROUP`, you can specify ...
- the read result that serves as a representative in representative binding: `LOOP AT it INTO DATA(wa) GROUP BY ... LOOP AT GROUP wa ...`.
- the group key binding: `LOOP AT it INTO DATA(wa) GROUP BY ... INTO gkb. ... LOOP AT GROUP gkb ...`.
- Additional syntax options like a `WHERE` condition and further grouping are also available.
More information:
- [Here (and the subtopics there)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm) in the ABAP Keyword Documentation
- Iteration expressions can also handle table grouping (`FOR ... IN GROUP`). For example, see the [Constructor Expressions](05_Constructor_Expressions.md) cheat sheet.
- [Internal Tables: Grouping](11_Internal_Tables_Grouping.md) cheat sheet
The example class below demonstrates internal table grouping options. To try it out, create a demo class named `zcl_some_class` and paste the following code into it. After activation, choose *F9* in ADT to execute the class. The example is designed to display results in the console.
```abap ```abap
TYPES: BEGIN OF demo_struct, CLASS zcl_some_class DEFINITION
a TYPE c LENGTH 1, PUBLIC
b TYPE i, FINAL
END OF demo_struct, CREATE PUBLIC .
tab_type TYPE TABLE OF demo_struct WITH EMPTY KEY.
DATA(it1) = VALUE tab_type( ( a = 'a' b = 1 )
( a = 'b' b = 5 )
( a = 'a' b = 3 )
( a = 'b' b = 4 )
( a = 'a' b = 2 )
( a = 'b' b = 6 )
( a = 'c' b = 10 )
( a = 'd' b = 0 )
( a = 'd' b = 7 )
( a = 'a' b = 4 )
( a = 'e' b = 11 )
( a = 'e' b = 111 ) ).
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
DATA it2 LIKE it1. PROTECTED SECTION.
SORT it1 BY a ASCENDING b DESCENDING. PRIVATE SECTION.
LOOP AT it1 INTO DATA(wa) GROUP BY wa-a. ENDCLASS.
LOOP AT GROUP wa INTO DATA(member).
APPEND member TO it2.
EXIT.
ENDLOOP.
ENDLOOP.
"Content of it2: CLASS zcl_some_class IMPLEMENTATION.
*A B METHOD if_oo_adt_classrun~main.
*a 4 TYPES: BEGIN OF demo_struct,
*b 6 comp1 TYPE c LENGTH 1,
*c 10 comp2 TYPE i,
*d 7 comp3 TYPE abap_boolean,
*e 111 comp4 TYPE string,
END OF demo_struct,
tab_type TYPE TABLE OF demo_struct WITH EMPTY KEY.
DATA str_table TYPE string_table.
"Populating a demo internal table as the basis of the syntax example
"Note: The example loops only use data objects as targets, not data references
"or field symbols.
DATA(it) = VALUE tab_type( ( comp1 = 'd' comp2 = 0 comp3 = abap_false )
( comp1 = 'a' comp2 = 1 comp3 = abap_true )
( comp1 = 'a' comp2 = 2 comp3 = abap_false )
( comp1 = 'e' comp2 = 11 comp3 = abap_true )
( comp1 = 'e' comp2 = 11 comp3 = abap_true )
( comp1 = 'b' comp2 = 5 comp3 = abap_true )
( comp1 = 'b' comp2 = 6 comp3 = abap_false )
( comp1 = 'a' comp2 = 3 comp3 = abap_false )
( comp1 = 'b' comp2 = 4 comp3 = abap_true )
( comp1 = 'c' comp2 = 10 comp3 = abap_true )
( comp1 = 'e' comp2 = 1 comp3 = abap_false )
( comp1 = 'd' comp2 = 7 comp3 = abap_true )
( comp1 = 'a' comp2 = 4 comp3 = abap_true )
( comp1 = 'e' comp2 = 111 comp3 = abap_true ) ).
"The following example (and several others below) does not specify a nested loop.
"It does not specify a group key binding either. This means that the work area
"contains the first line of each group, representing the group in the loop
"(representative binding). The comp4 component is assigned the sy-tabix value,
"which is the number of the line in the table without the grouping.
DATA ita LIKE it.
LOOP AT it INTO DATA(waa) GROUP BY waa-comp1.
waa-comp4 = sy-tabix.
APPEND waa TO ita.
ENDLOOP.
out->write( data = ita name = `ita` ).
"Specifying sort order
DATA itb LIKE it.
LOOP AT it INTO DATA(wab) GROUP BY wab-comp1 ASCENDING.
wab-comp4 = sy-tabix.
APPEND wab TO itb.
ENDLOOP.
out->write( data = itb name = `itb` ).
"WITHOUT MEMBERS addition; a group key binding is required
"after WITHOUT MEMBERS
"The group key binding is added to a string table for visualizing its
"content.
"Note: The component values are initial when the group key binding is
"specified.
LOOP AT it INTO DATA(wac) GROUP BY wac-comp1 WITHOUT MEMBERS INTO DATA(keyc).
ASSERT wac IS INITIAL.
APPEND keyc TO str_table.
ENDLOOP.
out->write( data = str_table name = `str_table` ).
"Using a structured group key
"The following example just assigns component values to the group key. In this case,
"the grouping is performed with more than just one criterion as in the previous examples.
"As a result, table lines are added to the other table in descending order based on the
"two component values.
DATA itd LIKE it.
LOOP AT it INTO DATA(wad) GROUP BY ( key1 = wad-comp1 key2 = wad-comp2 ) DESCENDING.
APPEND wad TO itd.
ENDLOOP.
out->write( data = itd name = `itd` ).
"In the following example, the group is sorted in ascending order. Note that the
"group index value uses the original position in the group index. The group key
"binding information is added to a string table for visualizing its content.
CLEAR str_table.
LOOP AT it INTO DATA(wae) GROUP BY ( key = wae-comp1 gi = GROUP INDEX gs = GROUP SIZE ) ASCENDING INTO DATA(keye).
ASSERT wae IS INITIAL.
APPEND |Key component: '{ keye-key }', group index: '{ keye-gi }', group size: '{ keye-gs }'| TO str_table.
ENDLOOP.
out->write( data = str_table name = `str_table` ).
"LOOP AT GROUP: Nested loop across group members
"Unlike the previous example, the example uses a nested loop across the groups (the group key binding is
"specified after LOOP AT GROUP). There, the component values of the members can be accessed.
DATA itf LIKE it.
LOOP AT it INTO DATA(waf) GROUP BY ( key = waf-comp1 gi = GROUP INDEX gs = GROUP SIZE ) ASCENDING INTO DATA(keyf).
ASSERT waf IS INITIAL.
LOOP AT GROUP keyf INTO DATA(memberf).
APPEND VALUE #( comp1 = memberf-comp1 comp2 = memberf-comp2 comp3 = memberf-comp3
comp4 = |Key component: '{ keyf-key }', group index: '{ keyf-gi }', group size: '{ keyf-gs }'|
) TO itf.
ENDLOOP.
ENDLOOP.
out->write( data = itf name = `itf` ).
"The objective of this example is to extract the line with the highest value in a particular
"column within a group (following the sorting) from the original table to another.
"The example uses representative binding, i.e. the representative of the group is specified
"in the work area, not in a group key binding.
DATA itg LIKE it.
LOOP AT it INTO DATA(wag) GROUP BY wag-comp1 ASCENDING.
LOOP AT GROUP wag INTO DATA(memberg) GROUP BY memberg-comp2 DESCENDING.
APPEND memberg TO itg.
EXIT.
ENDLOOP.
ENDLOOP.
out->write( data = itg name = `itg` ).
"The following example is similar to the previous example, and yields the same result.
"Here, the group key binding is specified after LOOP AT GROUP.
DATA ith LIKE it.
LOOP AT it INTO DATA(wah) GROUP BY wah-comp1 ASCENDING.
LOOP AT GROUP wah INTO DATA(memberh) GROUP BY memberh-comp2 DESCENDING.
APPEND memberh TO ith.
EXIT.
ENDLOOP.
ENDLOOP.
ASSERT itg = ith.
out->write( data = ith name = `ith` ).
"Additional syntax options, like specifying a WHERE condition in both nested and outer
"loops, are possible. The example below shows that the LOOP AT GROUP statement assigns
"the value of sy-tabix to the value that would be set for the current line in the LOOP
"without grouping.
DATA iti LIKE it.
LOOP AT it INTO DATA(wai) GROUP BY wai-comp1 ASCENDING.
LOOP AT GROUP wai INTO DATA(memberi) WHERE comp3 = abap_true.
APPEND VALUE #( comp1 = memberi-comp1 comp2 = memberi-comp2 comp3 = memberi-comp3
comp4 = |sy-tabix: '{ sy-tabix }'|
) TO iti.
ENDLOOP.
ENDLOOP.
out->write( data = iti name = `iti` ).
ENDMETHOD.
ENDCLASS.
``` ```
<p align="right"><a href="#top">⬆️ back to top</a></p> <p align="right"><a href="#top">⬆️ back to top</a></p>

View File

@@ -1,182 +1,181 @@
<a name="top"></a> <a name="top"></a>
# Internal Tables: Grouping # Internal Tables: Grouping
- [Internal Tables: Grouping](#internal-tables-grouping) - [Internal Tables: Grouping](#internal-tables-grouping)
- [Introduction](#introduction) - [Introduction](#introduction)
- [Grouping by One Column](#grouping-by-one-column) - [Grouping by One Column](#grouping-by-one-column)
- [Grouping by More than One Column](#grouping-by-more-than-one-column) - [Grouping by More than One Column](#grouping-by-more-than-one-column)
- [Group Key Binding when Grouping by One Column](#group-key-binding-when-grouping-by-one-column) - [Group Key Binding when Grouping by One Column](#group-key-binding-when-grouping-by-one-column)
- [Group Key Binding when Grouping by More than One Column](#group-key-binding-when-grouping-by-more-than-one-column) - [Group Key Binding when Grouping by More than One Column](#group-key-binding-when-grouping-by-more-than-one-column)
- [Executable Example](#executable-example) - [Executable Example](#executable-example)
## Introduction ## Introduction
Similar to SQL's [`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm), Similar to SQL's [`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm),
there is also a [`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm) there is also a [`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm)
for working with internal tables that can be used behind [`LOOP AT itab`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_variants.htm) for working with internal tables that can be used behind [`LOOP AT itab`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_variants.htm)
or in the form [`IN GROUP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor_in_group.htm) or in the form [`IN GROUP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor_in_group.htm)
in a table iteration with in a table iteration with
[`FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor_itab.htm). [`FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor_itab.htm).
It replaces the clumsy group level processing with statements [`AT NEW ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapat_itab.htm) It replaces the clumsy group level processing with statements [`AT NEW ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapat_itab.htm)
that relies on the order of table columns and content that is sorted that relies on the order of table columns and content that is sorted
respectively. respectively.
Thi cheat sheet explains the grouping of internal tables step by step Thi cheat sheet explains the grouping of internal tables step by step
using a very simple case of an internal table `spfli_tab` that using a very simple case of an internal table `spfli_tab` that
is filled with data from the database table `SPFLI`. The is filled with data from the database table `SPFLI`. The
following steps show how the content of the internal table can be following steps show how the content of the internal table can be
grouped using [`LOOP AT GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm). grouped using [`LOOP AT GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm).
## Grouping by One Column ## Grouping by One Column
The simplest form of grouping is by one column without explicitly The simplest form of grouping is by one column without explicitly
specifying the output behavior of the group loop: specifying the output behavior of the group loop:
``` abap ``` abap
LOOP AT spfli_tab INTO wa LOOP AT spfli_tab INTO wa
                  GROUP BY wa-carrid.                   GROUP BY wa-carrid.
       ... wa-carrid ...        ... wa-carrid ...
ENDLOOP. ENDLOOP.
``` ```
Within the loop, there is access to the work area `wa`, in Within the loop, there is access to the work area `wa`, in
particular to the component `wa-carrid` that is used for particular to the component `wa-carrid` that is used for
grouping. The work area `wa` contains the first line of each grouping. The work area `wa` contains the first line of each
group and represents the group in the loop. This is called group and represents the group in the loop. This is called
representative binding. representative binding.
To access the members of a group, a member loop can be inserted into the To access the members of a group, a member loop can be inserted into the
group loop: group loop:
``` abap ``` abap
LOOP AT spfli_tab INTO wa LOOP AT spfli_tab INTO wa
GROUP BY wa-carrid. GROUP BY wa-carrid.
  ...   ...
LOOP AT GROUP wa INTO DATA(member). LOOP AT GROUP wa INTO DATA(member).
    ... member-... ...     ... member-... ...
ENDLOOP. ENDLOOP.
  ...   ...
ENDLOOP. ENDLOOP.
``` ```
The member loop is executed using the group represented by `wa` The member loop is executed using the group represented by `wa`
and its members are assigned to `member` and are available in and its members are assigned to `member` and are available in
the member loop. the member loop.
<p align="right"><a href="#top">⬆️ back to top</a></p> <p align="right"><a href="#top">⬆️ back to top</a></p>
## Grouping by More than One Column ## Grouping by More than One Column
To group by more than just one criterion, a structured group key is To group by more than just one criterion, a structured group key is
defined as follows. In the simplest case, the grouping criteria are defined as follows. In the simplest case, the grouping criteria are
columns of the internal table: columns of the internal table:
``` abap ``` abap
LOOP AT spfli_tab INTO wa LOOP AT spfli_tab INTO wa
GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ). GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ).
  ... wa-carrid ... wa-airpfrom ...   ... wa-carrid ... wa-airpfrom ...
ENDLOOP. ENDLOOP.
``` ```
This is also a representative binding in which the work area This is also a representative binding in which the work area
`wa` is reused in the group loop to access the group key. `wa` is reused in the group loop to access the group key.
To access the members of the groups, the exact same member loop can be To access the members of the groups, the exact same member loop can be
inserted as when grouping by one column. inserted as when grouping by one column.
<p align="right"><a href="#top">⬆️ back to top</a></p> <p align="right"><a href="#top">⬆️ back to top</a></p>
## Group Key Binding when Grouping by One Column ## Group Key Binding when Grouping by One Column
By explicitly specifying an [output By explicitly specifying an [output
area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_binding.htm) area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_binding.htm)
for the group key, a group key binding can be defined explicitly instead for the group key, a group key binding can be defined explicitly instead
of the representative binding in which the output area of the group loop of the representative binding in which the output area of the group loop
is reused: is reused:
``` abap ``` abap
LOOP AT spfli_tab INTO wa LOOP AT spfli_tab INTO wa
GROUP BY wa-carrid GROUP BY wa-carrid
INTO DATA(key). INTO DATA(key).
  ... key ...   ... key ...
ENDLOOP. ENDLOOP.
``` ```
The difference to the example with representative binding is the The difference to the example with representative binding is the
`INTO` addition after `GROUP BY`. Instead of reusing `INTO` addition after `GROUP BY`. Instead of reusing
`wa`, an elementary data object `key` represents the `wa`, an elementary data object `key` represents the
group. This can be generated inline. The additions [`GROUP group. This can be generated inline. The additions [`GROUP
SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm), SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm),
[`GROUP [`GROUP
INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm), INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm),
and [`WITHOUT and [`WITHOUT
MEMBERS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm) MEMBERS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm)
can only be used in the group key binding, which gives it more functions can only be used in the group key binding, which gives it more functions
than the representative binding. If these are not required, the than the representative binding. If these are not required, the
representative binding can be used. The group key binding can also be representative binding can be used. The group key binding can also be
used to make the use of the group key in the loop more explicit. used to make the use of the group key in the loop more explicit.
Inserting a member loop works in the same way as in the representative Inserting a member loop works in the same way as in the representative
binding, with the difference that a group is now addressed by binding, with the difference that a group is now addressed by
`key` instead of `wa`. `key` instead of `wa`.
``` abap ``` abap
LOOP AT spfli_tab INTO wa  LOOP AT spfli_tab INTO wa 
GROUP BY wa-carrid  GROUP BY wa-carrid 
INTO key. INTO key.
  ...   ...
LOOP AT GROUP key INTO member. LOOP AT GROUP key INTO member.
    ... members ...     ... members ...
ENDLOOP. ENDLOOP.
  ...   ...
ENDLOOP. ENDLOOP.
``` ```
<p align="right"><a href="#top">⬆️ back to top</a></p> <p align="right"><a href="#top">⬆️ back to top</a></p>
## Group Key Binding when Grouping by More than One Column ## Group Key Binding when Grouping by More than One Column
Finally, the group key binding for structured group keys: Finally, the group key binding for structured group keys:
``` abap ``` abap
LOOP AT spfli_tab INTO wa LOOP AT spfli_tab INTO wa
GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ) GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom )
INTO DATA(key). INTO DATA(key).
  ... key-key1 ... key-key2 ...   ... key-key1 ... key-key2 ...
ENDLOOP. ENDLOOP.
``` ```
Here, `key` is a structure with the components `key1` Here, `key` is a structure with the components `key1`
and `key2`. A member loop can be inserted in exactly the same and `key2`. A member loop can be inserted in exactly the same
way as when grouping by one column. way as when grouping by one column.
If the group members are not relevant, the addition [`NO If the group members are not relevant, the addition [`WITHOUT MEMBERS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm)
MEMBERS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by.htm) can be used to save time and memory.
can be used to save time and memory.
``` abap
``` abap LOOP AT spfli_tab INTO wa
LOOP AT spfli_tab INTO wa GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom
GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom index = GROUP INDEX size = GROUP SIZE )
index = GROUP INDEX size = GROUP SIZE ) WITHOUT MEMBERS
WITHOUT MEMBERS INTO DATA(key).
INTO DATA(key).   ... key-key1 ... key-key2 ... key-index ... key-size ...
  ... key-key1 ... key-key2 ... key-index ... key-size ... ENDLOOP.
ENDLOOP. ```
```
It is no longer possible to use a member loop here. Instead, the group
It is no longer possible to use a member loop here. Instead, the group key was enriched with optional components for further information using
key was enriched with optional components for further information using [`GROUP
[`GROUP INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm)
INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm) [`GROUP
[`GROUP SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm).
SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm).
<p align="right"><a href="#top">⬆️ back to top</a></p>
<p align="right"><a href="#top">⬆️ back to top</a></p>
## Executable Example
## Executable Example
[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap)
[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap)
> **💡 Note**<br>
> **💡 Note**<br> > - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
> - [Disclaimer](README.md#%EF%B8%8F-disclaimer) > - [Disclaimer](README.md#%EF%B8%8F-disclaimer)