diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md index 808b7cb..763d0c6 100644 --- a/01_Internal_Tables.md +++ b/01_Internal_Tables.md @@ -1835,46 +1835,195 @@ it_ref = NEW #( ). ## 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 -TYPES: BEGIN OF demo_struct, - a TYPE c LENGTH 1, - b TYPE i, - END OF demo_struct, - 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 ) ). +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. -DATA it2 LIKE it1. -SORT it1 BY a ASCENDING b DESCENDING. -LOOP AT it1 INTO DATA(wa) GROUP BY wa-a. - LOOP AT GROUP wa INTO DATA(member). - APPEND member TO it2. - EXIT. - ENDLOOP. -ENDLOOP. + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. -"Content of it2: -*A B -*a 4 -*b 6 -*c 10 -*d 7 -*e 111 +CLASS zcl_some_class IMPLEMENTATION. + METHOD if_oo_adt_classrun~main. + TYPES: BEGIN OF demo_struct, + comp1 TYPE c LENGTH 1, + comp2 TYPE i, + comp3 TYPE abap_boolean, + 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. ```

⬆️ back to top

diff --git a/11_Internal_Tables_Grouping.md b/11_Internal_Tables_Grouping.md index 72a2883..2f14f6e 100644 --- a/11_Internal_Tables_Grouping.md +++ b/11_Internal_Tables_Grouping.md @@ -1,182 +1,181 @@ - - -# Internal Tables: Grouping - -- [Internal Tables: Grouping](#internal-tables-grouping) - - [Introduction](#introduction) - - [Grouping by One Column](#grouping-by-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 More than One Column](#group-key-binding-when-grouping-by-more-than-one-column) - - [Executable Example](#executable-example) - - -## 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), -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) -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 -[`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) -that relies on the order of table columns and content that is sorted -respectively. - -Thi cheat sheet explains the grouping of internal tables step by step -using a very simple case of an internal table `spfli_tab` that -is filled with data from the database table `SPFLI`. The -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). - -## Grouping by One Column - -The simplest form of grouping is by one column without explicitly -specifying the output behavior of the group loop: - -``` abap -LOOP AT spfli_tab INTO wa -                  GROUP BY wa-carrid. -       ... wa-carrid ... -ENDLOOP. -``` - -Within the loop, there is access to the work area `wa`, in -particular to the component `wa-carrid` that is used for -grouping. The work area `wa` contains the first line of each -group and represents the group in the loop. This is called -representative binding. - -To access the members of a group, a member loop can be inserted into the -group loop: -``` abap -LOOP AT spfli_tab INTO wa - GROUP BY wa-carrid. -  ... - LOOP AT GROUP wa INTO DATA(member). -    ... member-... ... - ENDLOOP. -  ... -ENDLOOP. -``` - -The member loop is executed using the group represented by `wa` -and its members are assigned to `member` and are available in -the member loop. - -

⬆️ back to top

- -## Grouping by More than One Column - -To group by more than just one criterion, a structured group key is -defined as follows. In the simplest case, the grouping criteria are -columns of the internal table: - -``` abap -LOOP AT spfli_tab INTO wa - GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ). -  ... wa-carrid ... wa-airpfrom ... -ENDLOOP. -``` - -This is also a representative binding in which the work area -`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 -inserted as when grouping by one column. - -

⬆️ back to top

- -## Group Key Binding when Grouping by One Column - -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) -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 -is reused: - -``` abap -LOOP AT spfli_tab INTO wa - GROUP BY wa-carrid - INTO DATA(key). -  ... key ... -ENDLOOP. -``` - -The difference to the example with representative binding is the -`INTO` addition after `GROUP BY`. Instead of reusing -`wa`, an elementary data object `key` represents the -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), -[`GROUP -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 -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 -than the representative binding. If these are not required, the -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. - -Inserting a member loop works in the same way as in the representative -binding, with the difference that a group is now addressed by -`key` instead of `wa`. - -``` abap -LOOP AT spfli_tab INTO wa  - GROUP BY wa-carrid  - INTO key. -  ... - LOOP AT GROUP key INTO member. -    ... members ... - ENDLOOP. -  ... -ENDLOOP. -``` - -

⬆️ back to top

- -## Group Key Binding when Grouping by More than One Column -Finally, the group key binding for structured group keys: - -``` abap -LOOP AT spfli_tab INTO wa - GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ) - INTO DATA(key). -  ... key-key1 ... key-key2 ... -ENDLOOP. -``` - -Here, `key` is a structure with the components `key1` -and `key2`. A member loop can be inserted in exactly the same -way as when grouping by one column. - -If the group members are not relevant, the addition [`NO -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. - -``` abap -LOOP AT spfli_tab INTO wa - GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom - index = GROUP INDEX size = GROUP SIZE ) - WITHOUT MEMBERS - INTO DATA(key). -  ... key-key1 ... key-key2 ... key-index ... key-size ... -ENDLOOP. -``` - -It is no longer possible to use a member loop here. Instead, the group -key was enriched with optional components for further information using -[`GROUP -INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm) -[`GROUP -SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm). - -

⬆️ back to top

- -## Executable Example - -[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap) - -> **💡 Note**
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples). + + +# Internal Tables: Grouping + +- [Internal Tables: Grouping](#internal-tables-grouping) + - [Introduction](#introduction) + - [Grouping by One Column](#grouping-by-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 More than One Column](#group-key-binding-when-grouping-by-more-than-one-column) + - [Executable Example](#executable-example) + + +## 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), +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) +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 +[`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) +that relies on the order of table columns and content that is sorted +respectively. + +Thi cheat sheet explains the grouping of internal tables step by step +using a very simple case of an internal table `spfli_tab` that +is filled with data from the database table `SPFLI`. The +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). + +## Grouping by One Column + +The simplest form of grouping is by one column without explicitly +specifying the output behavior of the group loop: + +``` abap +LOOP AT spfli_tab INTO wa +                  GROUP BY wa-carrid. +       ... wa-carrid ... +ENDLOOP. +``` + +Within the loop, there is access to the work area `wa`, in +particular to the component `wa-carrid` that is used for +grouping. The work area `wa` contains the first line of each +group and represents the group in the loop. This is called +representative binding. + +To access the members of a group, a member loop can be inserted into the +group loop: +``` abap +LOOP AT spfli_tab INTO wa + GROUP BY wa-carrid. +  ... + LOOP AT GROUP wa INTO DATA(member). +    ... member-... ... + ENDLOOP. +  ... +ENDLOOP. +``` + +The member loop is executed using the group represented by `wa` +and its members are assigned to `member` and are available in +the member loop. + +

⬆️ back to top

+ +## Grouping by More than One Column + +To group by more than just one criterion, a structured group key is +defined as follows. In the simplest case, the grouping criteria are +columns of the internal table: + +``` abap +LOOP AT spfli_tab INTO wa + GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ). +  ... wa-carrid ... wa-airpfrom ... +ENDLOOP. +``` + +This is also a representative binding in which the work area +`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 +inserted as when grouping by one column. + +

⬆️ back to top

+ +## Group Key Binding when Grouping by One Column + +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) +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 +is reused: + +``` abap +LOOP AT spfli_tab INTO wa + GROUP BY wa-carrid + INTO DATA(key). +  ... key ... +ENDLOOP. +``` + +The difference to the example with representative binding is the +`INTO` addition after `GROUP BY`. Instead of reusing +`wa`, an elementary data object `key` represents the +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), +[`GROUP +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 +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 +than the representative binding. If these are not required, the +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. + +Inserting a member loop works in the same way as in the representative +binding, with the difference that a group is now addressed by +`key` instead of `wa`. + +``` abap +LOOP AT spfli_tab INTO wa  + GROUP BY wa-carrid  + INTO key. +  ... + LOOP AT GROUP key INTO member. +    ... members ... + ENDLOOP. +  ... +ENDLOOP. +``` + +

⬆️ back to top

+ +## Group Key Binding when Grouping by More than One Column +Finally, the group key binding for structured group keys: + +``` abap +LOOP AT spfli_tab INTO wa + GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ) + INTO DATA(key). +  ... key-key1 ... key-key2 ... +ENDLOOP. +``` + +Here, `key` is a structure with the components `key1` +and `key2`. A member loop can be inserted in exactly the same +way as when grouping by one column. + +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) +can be used to save time and memory. + +``` abap +LOOP AT spfli_tab INTO wa + GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom + index = GROUP INDEX size = GROUP SIZE ) + WITHOUT MEMBERS + INTO DATA(key). +  ... key-key1 ... key-key2 ... key-index ... key-size ... +ENDLOOP. +``` + +It is no longer possible to use a member loop here. Instead, the group +key was enriched with optional components for further information using +[`GROUP +INDEX`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm) +[`GROUP +SIZE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_group_by_key.htm). + +

⬆️ back to top

+ +## Executable Example + +[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap) + +> **💡 Note**
+> - 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) \ No newline at end of file