diff --git a/03_ABAP_SQL.md b/03_ABAP_SQL.md
index d769fe3..5767b8f 100644
--- a/03_ABAP_SQL.md
+++ b/03_ABAP_SQL.md
@@ -1240,282 +1240,31 @@ SELECT *
## SQL Conditions
-You can formulate conditions in ABAP SQL statements, i. e. [logical
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm "Glossary Entry"),
-especially in the `WHERE` clause to restrict the result. Note
-that without a `WHERE` clause, all rows are respected for the
-operation.
+You can formulate conditions in ABAP SQL statements, i. e. [logical expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm "Glossary Entry"), especially in the `WHERE` clause to restrict the result. Note that without a `WHERE` clause, all rows are respected for the operation.
-See below a selection of the operators that are possible when specifying
-conditions. For more information, see the subtopics of the [SQL
-Conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenasql_cond.htm)
-topic.
+Find more details and examples in the [WHERE Conditions](31_WHERE_Conditions.md) cheat sheet.
-| Operator | Meaning |
-|----------|:-------------:|
-| `=`, `EQ` | The content of two operands is equal.|
-| `<>`, `NE` | The content of two operands is not equal.|
-| `<`, `LT` | The content of one operand is less than the content of the other operand.|
-| `>`, `GT` | The content of one operand is greater than the content of the other operand.|
-| `<=`, `LE` | The content of one operand is less than or equal to the content of the other operand.|
-| `>=`, `GE` | The content of one operand is greater than or equal to the content of the other operand.|
-| `... [NOT] BETWEEN ... AND ...` | The value of an operand is (not) between the value of the two other operands.|
-| `... [NOT] LIKE ...` | The content of an operand matches (does not match) a specified pattern. The pattern can be specified by using wildcard characters. `%` stands for any character string, including an empty string. `_` stands for any character.|
-| `... IS [NOT] INITIAL ...` | The value of an operand is (not) the initial value of its built-in dictionary type.|
-| `... EXISTS ...` | Checks the result set of a [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry"). The expression is true if the result set contains at least one row. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_subquery.htm).|
-| `... [NOT] IN ...` | Checks whether the operands on the left side match a value from a set of values specified in parentheses. On the left side, a single operand or an operand list are possible. On the right side, a comma-separated lists or subqueries can be specified. It is also possible to specify a [ranges table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_table_glosry.htm) to evaluate [ranges conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_condition_glosry.htm).|
-| `... IS [NOT] NULL ...` | Checks whether the value of an operand is (not) the [null value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm). Find more information in the code snippet and in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_null.htm). |
+Among the syntax options are:
-> **💡 Note**
->You can combine multiple logical expressions into one
-logical expression using `AND` or `OR`. To further
-detail out the desired condition, expressions within parentheses are
-possible. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_andornot.htm).
-
-Examples:
-
-``` abap
-"---- SQL conditions demonstrated with the WHERE clause ----
-"Note:
-"- For most of the self-contained examples, an internal table is used as the
-" data source of SELECT statements to work with simple data.
-"- For some examples that are covered, such as subqueries, demo database tables
-" from the cheat sheet repository are used in addition.
-"- Dynamic specifications are also possible. They are not covered here. See
-" the Dynamic Programming cheat sheet.
-
-"---- Types and internal table to work with in the examples ----
-"Note: You cannot use type string columns in WHERE conditions.
-TYPES: BEGIN OF demo_struc,
- id TYPE i,
- name TYPE c LENGTH 15,
- "name TYPE string,
- END OF demo_struc.
-DATA itab TYPE SORTED TABLE OF demo_struc WITH UNIQUE KEY id.
-"Populating internal table with data to work with in the examples
-itab = VALUE #( ( id = 1 name = 'bear' )
- ( id = 2 name = 'camel' )
- ( id = 3 name = 'rabbit' )
- ( id = 4 name = 'zebra' )
- ( id = 5 name = 'dog' )
- ( id = 6 name = 'deer' )
- ( id = 7 name = 'squirrel' )
- ( id = 8 name = 'cheetah' )
- ( id = 9 name = 'elephant' )
- ( id = 10 name = 'donkey' )
- ( id = 11 name = 'fish' )
- ( id = 12 name = 'sheep' ) ).
-
-"---- =, <>, >, >= (as a selection of possible comparison operators) ----
-SELECT id FROM @itab AS tab WHERE name = 'bear' INTO TABLE @DATA(it). "1
-SELECT id FROM @itab AS tab WHERE name <> 'bear' INTO TABLE @it. "2-12
-SELECT id FROM @itab AS tab WHERE id > 10 INTO TABLE @it. "11,12
-SELECT id FROM @itab AS tab WHERE id >= 10 INTO TABLE @it. "10,11,12
-
-"---- Combining logical expressions using AND, OR and parentheses ----
-SELECT id FROM @itab AS tab WHERE id = 1 AND name = 'bear' INTO TABLE @it. "1
-SELECT id FROM @itab AS tab WHERE name = 'bear' OR name = 'sheep' INTO TABLE @it. "1,12
-
-"In the following example, the resulting table is initial. One of the expressions
-"in parentheses is false (AND is used between the expressions in parentheses).
-"In contrast, the example below returns an entry because of using OR.
-SELECT id FROM @itab AS tab
- WHERE ( id = 1 AND name = 'bear' )
- AND ( id = 20 AND name = 'camel' )
- INTO TABLE @it.
-
-SELECT id FROM @itab AS tab
- WHERE ( id = 1 AND name = 'bear' )
- OR ( id = 20 AND name = 'camel' )
- INTO TABLE @it. "1
-
-"------------------------ [NOT] BETWEEN ------------------------
-SELECT id FROM @itab AS tab WHERE id BETWEEN 1 AND 4 INTO TABLE @it. "1,2,3,4
-"The condition with BETWEEN above corresponds to the following condition.
-"The example makes use of a condition specified in parentheses to combine multiple
-"expressions.
-SELECT id FROM @itab AS tab WHERE ( id >= 1 AND id <= 4 ) INTO TABLE @it. "1,2,3,4
-"Negation with NOT
-SELECT id FROM @itab AS tab WHERE id NOT BETWEEN 1 AND 4 INTO TABLE @it. "5-12
-
-"------------------------ IS [NOT] INITIAL ------------------------
-SELECT id FROM @itab AS tab WHERE id IS NOT INITIAL INTO TABLE @it. "1-12
-
-SELECT id FROM @itab AS tab WHERE id IS INITIAL INTO TABLE @it. "No entry
-
-"------------------------ [NOT] LIKE ------------------------
-"For (not) matching a specified pattern
-"Note: % (any character string), _ (any character).
-SELECT name FROM @itab AS tab
- WHERE name LIKE '%ee%'
- OR name LIKE '_o%'
- INTO TABLE @DATA(names). "dog,deer,cheetah,donkey,sheep
-
-SELECT name FROM @itab AS tab
- WHERE name NOT LIKE '%ee%'
- INTO TABLE @names. "All except deer, cheetah, sheep
-
-"ESCAPE addition for defining a single-character escape character
-"In the following example, this character is #. It is placed before
-"the % character in the specification after LIKE. In this case, %
-"is escaped and does then not stand for any character string in the
-"evaluation.
-"Adding a table entry for this syntax example.
-itab = VALUE #( BASE itab ( id = 13 name = '100%' ) ).
-"Any character sequence followed by the % character
-SELECT name FROM @itab AS tab
- WHERE name LIKE '%#%' ESCAPE '#'
- INTO TABLE @names. "100%
-
-"Deleting the entry because it is not relevant for the further examples.
-DELETE itab INDEX 13.
-
-"------------------------ [NOT] IN (using a value set) ------------------------
-"For (not) matching a value in a set of values specified in parentheses.
-
-"Single operands on the left side of IN
-SELECT id FROM @itab AS tab
- WHERE name IN ( 'camel', 'rabbit', 'dog', 'snake' )
- INTO TABLE @it. "2,3,5
-
-"Negation NOT IN; note to use host variables/expressions for local/global data objects
-DATA(animal) = 'sheep'.
-SELECT id FROM @itab AS tab
- WHERE name NOT IN ( 'fish', @animal )
- INTO TABLE @it. "1-10
-
-"Operand list (a parenthesized comma-separated list) on the left side of IN
-"For (not) matching value tuples from a set of value tuples specified in parentheses on the right side.
-"In the following example, two values are specified in the operand list on the left. Consequently,
-"two values with appropriate types must be specified in parentheses on the right.
-SELECT id FROM @itab AS tab
- WHERE ( id, name ) IN ( ( 1, 'bear' ), ( 3, 'rabbit' ), ( 8, 'zebra' ), ( 20, 'dog' ) )
- INTO TABLE @it. "1,3
-
-
-"------------------------ [NOT] IN (using a subquery) ------------------------
-"[NOT] IN for matching a value contained in the result set of a subquery
-
-"In the following example, the subquery reads data from a demo database table.
-"For a representative result, the table is cleared, and then filled with 'suitable'
-"data sets.
-DELETE FROM zdemo_abap_tab1.
-MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 11 num1 = 11 )
- ( key_field = 12 num1 = 12 )
- ( key_field = 13 num1 = 13 )
- ( key_field = 14 num1 = 14 ) ) ).
-
-SELECT id FROM @itab AS tab
- WHERE id IN ( SELECT key_field FROM zdemo_abap_tab1 ) INTO TABLE @it. "11,12
-
-"------------------------ [NOT] IN (using a ranges table) ------------------------
-"[NOT] IN for checking whether the operands on the left side match a ranges condition in a ranges table
-
-"Declaring a ranges table
-DATA rangestab TYPE RANGE OF i.
-"Populating a ranges table using the VALUE operator
-rangestab = VALUE #( ( sign = 'I' option = 'BT' low = 1 high = 3 )
- ( sign = 'I' option = 'GE' low = 10 ) ).
-
-SELECT id FROM @itab AS tab WHERE id IN @rangestab INTO TABLE @it. "1,2,3,10,11,12
-
-
-"You cannot use logical operators such as CP (conforms to pattern) in the WHERE clause.
-"In a ranges table, they are possible.
-"Note:
-"- Regarding CP: * (any character sequence), + (any character), # (escape character)
-"- An equivalent example above uses the LIKE addition.
-DATA rt TYPE RANGE OF demo_struc-name.
-rt = VALUE #( ( sign = 'I' option = 'CP' low = '*ee*' ) "ee in a string
- ( sign = 'I' option = 'CP' low = '+o*' ) ). "o in second position
-SELECT name FROM @itab AS tab
- WHERE name IN @rt
- INTO TABLE @names. "dog,deer,cheetah,donkey,sheep
-
-"------------------------ EXISTS ------------------------
-"For checking the result set of a subquery.
-"The following example reads all entries from the internal table if entries having
-"the same key also exist in the database table.
-"Note: The SELECT list in the subquery only contains a literal to determine that
-"the entry exists. Specifying explicit column names is not relevant.
-SELECT id FROM @itab AS tab WHERE
- EXISTS ( SELECT @abap_true FROM zdemo_abap_tab1 WHERE key_field = tab~id )
- INTO TABLE @it. "11,12
-
-"------------------------ IS [NOT] NULL ------------------------
-"The null value is a special value that is returned by a database. It indicates an
-"undefined value or result. Note that, in ABAP, there are no special null values. Do
-"not confuse the null value with a type-dependent initial value. When using SELECT
-"statements to read data, null values can be produced by, for example, outer joins.
-"When the null values are passed to a data object, they are transformed to the
-"type-dependent initial values. For more information, refer to the ABAP Keyword Documentation.
-"The following example uses a left outer join to intentionally create null values. For
-"this purpose, two demo database tables of the cheat sheet repository are cleared and
-"populated with specific values to visualize null values.
-DELETE FROM zdemo_abap_tab1.
-DELETE FROM zdemo_abap_tab2.
-MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' char2 = 'y' )
- ( key_field = 2 char1 = 'b' char2 = 'z' ) ) ).
-MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' )
- ( key_field = 2 char1 = 'a' )
- ( key_field = 3 char1 = 'b' )
- ( key_field = 4 ) ) ).
-"Note that for the entry 'key_field = 4' no char1 value was passed.
-"char1 is a shared column of the two database tables, and which is used in
-"the ON condition of the join. Since there is no entry in char1 for 'key_field = 4',
-"the joined values are null in that case. The WHERE clause uses the addition IS NULL.
-"Therefore, the result only contains this entry. char2 is assigned the type-initial
-"value in the result.
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- WHERE tab1~char1 IS NULL
- INTO TABLE @DATA(joined_tab).
-*KEY_FIELD CHAR2
-*4
-
-"The following example visualizes the null values. The INDICATORS addition of the
-"INTO clause is used to specify indicators such as the null indicator. In the
-"example, an appropriate target table is defined to also store information about
-"which columns of the result set contain the null value and which do not.
-"For more information on the syntax, refer to the ABAP Keyword Documentation.
-TYPES: BEGIN OF st4null,
- BEGIN OF s2,
- key_field TYPE zdemo_abap_tab2-key_field,
- char2 TYPE zdemo_abap_tab1-char2,
- END OF s2,
- BEGIN OF nulls,
- key_field TYPE c LENGTH 1,
- char2 TYPE c LENGTH 1,
- END OF nulls,
- END OF st4null.
-DATA joined_tab_w_null_ind TYPE TABLE OF st4null WITH EMPTY KEY.
-
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- INTO TABLE @joined_tab_w_null_ind INDICATORS NULL STRUCTURE nulls.
-*S2 NULLS
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*1 y
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*2 y
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*3 z
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*4 X
-
-"Negation IS NOT NULL
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- WHERE tab1~char1 IS NOT NULL
- INTO TABLE @joined_tab.
-*KEY_FIELD CHAR2
-*1 y
-*2 y
-*3 z
-```
+- `... a = b ...` / `... a EQ b ...`
+- `... a <> b ...` / `... a NE b ...`
+- `... a < b ...` / `... a LT b ...`
+- `... a > b ...` / `... a GT b ...`
+- `... a <= b ...` / `... a LE b ...`
+- `... a >= b ...` / `... a GE b ...`
+- `... AND ...` / `... OR ...` / `... ( ... ) ...`
+- `... a [=|<>|>|<|...] [ALL|ANY|SOME] ( SELECT ... ) ...`
+- `... a [NOT] BETWEEN b AND c ...`
+- `... a [NOT] LIKE b [ESCAPE c] ...`
+- `... a IS [NOT] INITIAL ...`
+- `... a [NOT] IN (b, c, ...)...`
+- `... a [NOT] IN ( SELECT ... ) ...`
+- `... ( a, b, ... ) IN ( ( d, e, ... ) ( f, g, ...) ... ) ...`
+- `... ( a, b, ... ) IN ( SELECT ... ) ...`
+- `... a [NOT] IN @ranges_table ...`
+- `... EXISTS ( SELECT ... ) ...`
+- `... a IS [NOT] NULL ...`
+- `... (dynamic_where_clause) ...`
| Syntax Variant | Notes | Code Snippet | +
|
+
+`... a = b ...` `... a EQ b ...` + + |
+
+ + + The content of two operands is equal. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE animal = 'bear' + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE animal EQ 'bear' + INTO TABLE @it. +``` + + | +
|
+
+`... a <> b ...` `... a NE b ...` + + |
+
+ + +The content of two operands is not equal. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE animal <> 'bear' + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE animal NE 'bear' + INTO TABLE @it. +``` + + | +
|
+
+`... a < b ...` `... a LT b ...` + + |
+
+ + +The content of the left operand is less than the content of the right operand. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count < 15 + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE count LT 15 + INTO TABLE @it. +``` + + | +
|
+
+`... a > b ...` `... a GT b ...` + + |
+
+ + +The content of the left operand is greater than the content of the right operand. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count > 15 + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE count GT 15 + INTO TABLE @it. +``` + + | +
|
+
+`... a <= b ...` `... a LE b ...` + + |
+
+ + +The content of the left operand is less than or equal to the content of the right operand. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count <= 15 + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE count LE 15 + INTO TABLE @it. +``` + + | +
|
+
+`... a >= b ...` `... a GE b ...` + + |
+
+ + +The content of the left operand is greater than or equal to the content of the right operand. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count >= 15 + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE count GE 15 + INTO TABLE @it. +``` + + | +
|
+
+`... AND ...` `... OR ...` `... ( ... ) ...` + + |
+
+ + +Combining multiple logical expressions into one logical expression using `AND` or `OR`. To further detail out the desired condition, expressions within parentheses are possible. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE id = 1 AND animal = 'bear' + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE animal = 'kangaroo' OR count = 4 + INTO TABLE @it. + +SELECT id FROM @itab AS tab + WHERE ( id = 1 AND animal = 'bear' ) + OR ( id = 20 AND animal = 'lion' ) + INTO TABLE @it. +``` + + | +
| + +`... a [=|<>|>|<|...] [ALL|ANY|SOME] ( SELECT ... ) ...` + + | + ++ +The content of a single operand is compared with the result set of a scalar subquery using a comparison operator. Multiple subqueries can be included with `UNION`, `INTERSECT`, or `EXCEPT`. The additions `ALL`, `ANY`, and `SOME` can only be omitted if the subquery result set contains a single row. Otherwise, an exception occurs with a multi-row result set. One of the additions must be specified in the case of multi-row result set. For `ALL`, the expression is true if the comparison holds for all rows in the result set. For `ANY` or `SOME`, the expression is true if the comparison holds for at least one row. Using `=` or `EQ` with `ANY` or `SOME` is similar to using `IN (SELECT ...)`. + + | + ++ +``` abap +"The following example assumes there is a single-row result set of the subquery. +SELECT id FROM @itab AS tab + WHERE count = ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 = 40 ) + INTO TABLE @it. + +"ALL addition +SELECT id FROM @itab AS tab + WHERE count > ALL ( SELECT key_field FROM zdemo_abap_tab1 ) + INTO TABLE @it. + +"ANY addition +SELECT id FROM @itab AS tab + WHERE count = ANY ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 <= 40 ) + INTO TABLE @it. + +"SOME addition (yields the same result as the previous statement) +SELECT id FROM @itab AS tab + WHERE count = SOME ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 <= 40 ) + INTO TABLE @it. +``` + + | +
| + +`... a [NOT] BETWEEN b AND c ...` + + | + ++ +The content of the left operand is (not) between the value of the two other operands. The syntax variant is like specifying `... [NOT] ( a >= b AND a <= c ) ...`. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count BETWEEN 1 AND 10 + INTO TABLE @it. + +"Negation with NOT +SELECT id FROM @itab AS tab + WHERE count NOT BETWEEN 1 AND 10 + INTO TABLE @it. +``` + + | +
| + +`... a [NOT] LIKE b [ESCAPE c] ...` + + | + +
+
+Checks whether the content of the left operand matches (or does not match) a specified pattern. The pattern can be specified by using wildcard characters. `%` stands for any character string, including an empty string. `_` stands for any character. Using the `ESCAPE` addition, you can specify a single-character escape character of length 1 (e.g. `#`) in front of a wildcard character or the escaped character itsef. For example, to search for the pattern `100%`, you may use an expression such as the the following: `... LIKE '100#%' ESCAPE '#' ...`. + + |
+
+ + +``` abap +SELECT animal FROM @itab AS tab + WHERE animal LIKE '%ee%' + OR animal LIKE '_e%' + INTO TABLE @DATA(animals). + +"Negation with NOT +SELECT animal FROM @itab AS tab + WHERE animal NOT LIKE '_e%' + INTO TABLE @animals. + +"ESCAPE addition +"The following example matches any character sequence followed +"by the % character. +SELECT animal FROM @itab AS tab + WHERE animal LIKE '%#%' ESCAPE '#' + INTO TABLE @animals. +``` + + | +
| + +`... a IS [NOT] INITIAL ...` + + | + ++ +Checks whether the content of an operand is (not) the initial value of its [built-in DDIC type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuiltin_ddic_type_glosry.htm). + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count IS INITIAL + INTO TABLE @it. + +"Negation with NOT +SELECT id FROM @itab AS tab + WHERE count IS NOT INITIAL + INTO TABLE @it. +``` + + | +
| + +`... a [NOT] IN (b, c, ...)...` + + | + ++ +Checks whether the content of the left operand is (not) contained in a set of a parenthesized, comma-separated list of values. You can also specify just one operand in the parentheses. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE animal IN ( 'elephant', 'gorilla', 'dog', 'snake' ) + INTO TABLE @it. + +"Negation with NOT +SELECT id FROM @itab AS tab + WHERE animal NOT IN ( 'chimpanzee', 'dog', 'snake' ) + INTO TABLE @it. + +"Blanks after the first parentheses and before the second are not mandatory. +"This also applies to blanks within the parentheses. However, choose either +"to use the blanks or not. +SELECT id FROM @itab AS tab + WHERE animal IN ('elephant','gorilla','dog','snake') + INTO TABLE @it. +``` + + | +
| + +`... a [NOT] IN ( SELECT ... ) ...` + + | + ++ +Checks whether the content of the left operand is (not) contained in the result set of a scalar subquery. Note that multiple subqueries can be included using `UNION`, `INTERSECT`, `EXCEPT`. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE count IN ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 <= 40 ) + INTO TABLE @it. + +"Negation with NOT +SELECT id FROM @itab AS tab + WHERE count NOT IN ( SELECT key_field FROM zdemo_abap_tab1 WHERE num1 <= 40 ) + INTO TABLE @it. +``` + + | +
| + +`... ( a, b, ... ) IN ( ( d, e, ... ) ( f, g, ...) ... ) ...` + + | + ++ +Checks whether each of the values of multiple operands in a parenthesized, comma-separated list on the left side of `IN` matches value tuples in the same place specified in parentheses on the right side of `IN`. Unlike the syntax option `... a [NOT] IN (b, c, ...) ...`, this syntax option allows [SQL expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm) on the right side of `IN`. Note that a negation with `NOT` is not supported. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE ( id, animal ) IN ( ( 1, 'bear' ), ( 3, 'giraffe' ), ( 987, 'flamingo' ), ( 2, 'dog' ) ) + INTO TABLE @it. +``` + + | +
| + +`... ( a, b, ... ) IN ( SELECT ... ) ...` + + | + ++ +Checks whether each value of multiple operands in a parenthesized, comma-separated list on the left side of `IN` matches the content of a subquery result set. The result set must contain the same number of elements as specified in the parentheses on the left side of `IN`. As above, the position of elements in the result set is relevant. Note that multiple subqueries can be included using `UNION`, `INTERSECT`, `EXCEPT`, and that a negation with `NOT` is not supported. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE ( id, count ) IN ( SELECT key_field, num1 FROM zdemo_abap_tab1 ) + INTO TABLE @it. +``` + + | +
| + +`... a [NOT] IN @ranges_table ...` + + | + ++ +Checks whether the operand on the left side of `IN` matches (or does not match) [ranges conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_condition_glosry.htm) specified in a [ranges table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_table_glosry.htm). Note that the operators `CP` and `NP` are transformed into `LIKE` conditions (as a consequence, the conditions for `CP` and `NP` are case-sensitive). + + | + ++ +``` abap +DATA rangestab TYPE RANGE OF i. +"Value range between 1 and 10 +rangestab = VALUE #( ( sign = 'I' option = 'BT' low = 1 high = 10 ) ). + +SELECT id FROM @itab AS tab + WHERE count IN @rangestab + INTO TABLE @it. + +"Value range: Lower than 5 + greater than or equal to 25 +rangestab = VALUE #( ( sign = 'I' option = 'LT' low = 5 ) + ( sign = 'I' option = 'GE' low = 25 ) ). + +SELECT id FROM @itab AS tab + WHERE count IN @rangestab + INTO TABLE @it. +``` + + | +
| + +`... EXISTS ( SELECT ... ) ...` + + | + ++ +Checks the result of a subquery. The comparison is true if the result set contains at least one row. Note that data source fields specified in the subquery are not relevant. You may also just use a single literal representing a column. Note that multiple subqueries can be included using `UNION`, `INTERSECT`, `EXCEPT`. + + | + ++ +``` abap +SELECT id FROM @itab AS tab + WHERE EXISTS ( SELECT 'X' FROM zdemo_abap_tab1 WHERE key_field = tab~id ) + INTO TABLE @it. +``` + + | +
| + +`... a IS [NOT] NULL ...` + + | + ++ +Checks whether the value of an operand is (not) the [null value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm). Find more information in the executable example (which also includes the `INDICATORS NULL STRUCTURE` addition to the `INTO` clause) and in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_null.htm). + + | + ++ +``` abap +SELECT tab2~key_field, tab1~char2 + FROM zdemo_abap_tab2 AS tab2 + LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1 + WHERE tab1~char1 IS NULL + INTO TABLE @DATA(joined_tab). + +"Negation IS NOT NULL +SELECT tab2~key_field, tab1~char2 + FROM zdemo_abap_tab2 AS tab2 + LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1 + WHERE tab1~char1 IS NOT NULL + INTO TABLE @joined_tab. +``` + + | +
| + +`... (dynamic_where_clause) ...` + + | + ++ +Dynamic `WHERE` condition specified as parenthesized data objects. This data objects should contain the syntax of a logical expression. As `dynamic_where_clause`, a character-like data object or a standard table with character-like line type is expected. The syntax is not case-sensitive. For more information, see the [Dynamic Programming cheat sheet](06_Dynamic_Programming.md), also with respect to potential security risks regarding dynamic specifications. + + | + ++ +``` abap +DATA(dynamic_where_clause) = `count > 15`. + +SELECT id FROM @itab AS tab + WHERE (dynamic_where_clause) + INTO TABLE @it. + +DATA(dyn_where_cl_as_tab) = VALUE string_table( ( `animal = 'kangaroo'` ) + ( `OR` ) + ( `count = 4` ) ). + +SELECT id FROM @itab AS tab + WHERE (dyn_where_cl_as_tab) + INTO TABLE @it. +``` + + | +