Add WHERE Conditions cheat sheet
This commit is contained in:
295
03_ABAP_SQL.md
295
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**<br>
|
||||
>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) ...`
|
||||
|
||||
<p align="right"><a href="#top">⬆️ back to top</a></p>
|
||||
|
||||
|
||||
1834
31_WHERE_Conditions.md
Normal file
1834
31_WHERE_Conditions.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -99,6 +99,7 @@ ABAP cheat sheets[^1] ...
|
||||
|[Regular Expressions in ABAP](28_Regular_Expressions.md)|Includes an overview of common regular expressions and their use in ABAP through statements, built-in functions, and system classes|[zcl_demo_abap_regex](./src/zcl_demo_abap_regex.clas.abap)|
|
||||
|[Numeric Operations in ABAP](29_Numeric_Operations.md)|Explores various aspects of numeric operations and calculations in ABAP|- (The cheat sheet includes a copy and paste example class)|
|
||||
|[Generative AI](30_Generative_AI.md)|Provides references to detailed information on *Generative AI in ABAP Cloud* and explores released ABAP classes available in the *ABAP AI SDK powered by Intelligent Scenario Lifecycle Management*|- (The cheat sheet includes a copy and paste example class)|
|
||||
|[WHERE Conditions](31_WHERE_Conditions.md)|Explores syntax options in ABAP statements that include `WHERE` for data filtering|- (The cheat sheet includes copy and paste example classes)|
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user