Professional Documents
Culture Documents
Comparison Operators
(alternative abbreviations included where applicable):
= (EQ) Equal
< > (NE) Not equal
Discussed > (GT) Greater than
earlier. < (LT) Less than
> = (GE) Greater than or equal to
< = (LE) Less than or equal to
BETWEEN. . . AND Inclusive range
[NOT] IN Test against predefined set
IS [NOT] NULL Test for nulls
The AND Condition
Employee Table
Contrast the AND with the OR, below:
Last First Dept#
Name Name
Retrieve employees with last name Brown
and first name Mary. Brown Alan 401
Retrieve employees with last name Brown and Work in department 401, OR first
name Mary. (AND is evaluated first)
SELECT *
last_name first_name dept#
FROM Employee
---------- ---------- -----------
WHERE Last_Name = 'brown' Smith Mary 900
AND Dept# = 401 Brown Alan 401
OR First_Name = 'mary';
Parentheses and the Predicate
The use of the parentheses in this query illustrate the order of evaluation of AND and OR for
the query on the previous page.
SELECT *
FROM Employee last_name first_name dept#
WHERE (Last_Name = 'brown') ---------- ---------- -----------
AND (Dept# = 401 Brown Alan 401
OR First_Name = 'mary');
The IN Operator
Retrieve employee whose first names are in the following Employee Table
list (as a set). Last First Dept#
Name Name
SELECT *
FROM Employee Brown Alan 401
Submitting the request by prefixing it with the EXPLAIN keyword will yield the optimizer
rewrite of this query (see left hand page). Here it reveals an alternate and equivalent syntax.
. . . . Rewrite Equivalent:
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an
WHERE
all-rows scan with a condition of ("(DLM.Employee.first_name =
First_Name = 'allen'
'allen') OR (DLM.Employee.first_name = 'alan')") into Spool 1
OR
(group_amps), which is built locally on the AMPs. The size of
First_Name = 'alan';
Spool 1 is estimated with no confidence to be 7 rows (595 bytes).
The estimated time for this step is 0.02 seconds.
. . . .
The NOT IN Operator
Retrieve employee whose first names are NOT IN the Employee Table
following list (as a set).
Last First Dept#
Name Name
SELECT *
FROM Employee Brown Alan 401
WHERE First_Name NOT IN ('alan', 'allen');
Brown Allen 801
last_name first_name dept#
Brown Cary 567
---------- ---------- -----------
Brown Cary 567 Smith Mary 900
Smith Mary 900
Jones Jimmy 401
Jones Jimmy 401
Submitting the request by prefixing it with the EXPLAIN keyword will yield the optimizer
rewrite of this query (see left hand page). Here it reveals an alternate and equivalent syntax.
. . . . Rewrite Equivalent:
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way
of an all-rows scan with a condition of (DLM.Employee.first_name WHERE
<> 'alan') AND (DLM.Employee.first_name <> 'allen')") into Spool 1 First_Name <> 'allen'
(group_amps), which is built locally on the AMPs. The size of AND
Spool 1 is estimated with no confidence to be 20 rows (1,700 First_Name <> 'alan';
bytes). The estimated time for this step is 0.02 seconds.
. . . .
Exclusive OR
SELECT *
Brown Alan 401
FROM Employee
WHERE Dept# BETWEEN 401 and 567; Brown Allen 801
Brown ? 567
last_name first_name dept#
---------- ---------- ----------- Smith Mary ?
Jones Jimmy 401
Jones Jimmy 401
Brown Alan 401
Brown ? 567
Explanation
---------------------------------------------------------------------------------------------------------------------------------------
. . . .
3) We do an all-AMPs RETRIEVE step from customer_service.Employee by way of an all-rows
scan with a condition of ("(customer_service.Employee.dept# <= 567) AND
(customer_service.Employee.dept# >= 401)") into Spool 1 (group_amps), which is built
locally on the AMPs. The size of Spool 1 is estimated with no confidence to be 4 rows (340
bytes). The estimated time for this step is 0.02 seconds.
. . . .
NULL
Although you can set the displayed value for NULL in both BTEQ and SQL
Assistant, the default value is to display a ? (question mark).
Conditional Expressions and NULL
In SQL, the database only projects column values for those rows that contain data
that satisfy all of the WHERE CONDITIONS.
If columns for a row are not projected, it is not because the conditions evaluated
FALSE, but instead because they did not evaluate TRUE.
We will build on this logic throughout the course.
Observe:
SELECT *
FROM Employee
WHERE Dept# < 500 SELECT *
OR First_Name IS NULL; FROM Employee
WHERE Dept# = NULL;
last_name first_name dept#
---------- ---------- ----------- *** Failure 3731 The user must use IS
Jones Jimmy 401 NULL or IS NOT NULL to test for NULL
Brown Alan 401 values.
Brown ? 567
NOT NULL and the Business Question
SELECT *
FROM Employee
WHERE First_Name <> NULL;
*** Failure 3731 The user must use IS NULL or IS NOT NULL to test for NULL values.
Negating Conditions and Operators
Retrieve employees whose first names are in the following list (as a set).
. . . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an
EXPLAIN
all-rows scan with a condition of ("(DLM.Employee.first_name =
SELECT *
'allen') OR (DLM.Employee.first_name = 'alan')") into Spool 1
FROM Employee
(group_amps), which is built locally on the AMPs. The size of
WHERE First_Name
Spool 1 is estimated with no confidence to be 7 rows (595 bytes).
IN ('alan', 'allen');
The estimated time for this step is 0.02 seconds.
. . . .
The NOT IN Operator and NULL
The EXPLAIN of this query shows an alternate method for writing this.
. . . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way
of an all-rows scan with a condition of (DLM.Employee.first_name
<> 'alan') AND (DLM.Employee.first_name <> 'allen')") into Spool 1
(group_amps), which is built locally on the AMPs. The size of
Spool 1 is estimated with no confidence to be 20 rows (1,700
bytes). The estimated time for this step is 0.02 seconds.
. . . .
<> With OR vs. <> With AND
Contrast the previous (NOT IN) query result against these two query results.
Explanation
-------------------------------------------------------------------------------------------------
The EXPLAIN shows how
. . . .
the database correctly
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way
treats the NULL literal as a
of an all-rows scan with a condition of (
comparison.
"(DLM.Employee.dept# = 403) OR
((DLM.Employee.dept# = 401) OR
(DLM.Employee.dept# = NULL ))")
into Spool 1 (group_amps), which is built locally on the AMPs.
The size of Spool 1 is estimated with no confidence to be 4
Including NULL to an IN-List
Note the difference between this EXPLAIN and that for the
query on the previous page. Employee Table
Last First Dept#
SELECT * Name Name
FROM Employee
WHERE Dept# IS NULL Brown Alan 401
OR Dept# IN (401, 403);
Brown Allen 801
Explanation
---------------------------------------------------------------------------------------------------------------------
. . . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an
all-rows scan with a condition of (
"(DLM.Employee.department_number = 403) OR
((DLM.Employee.department_number = 401) OR
(DLM.Employee.department_number IS NULL ))") Note: IS NULL
into Spool 1 (group_amps), which is built locally on the AMPs.
The size of Spool 1 is estimated with no confidence to be 9 rows (1,323 bytes).
NULL Literal in a NOT IN-List
FROM Employee
Brown Alan 401
WHERE Dept# NOT IN (401, 403, null);
Brown Allen 801
Smith Mary ?
The EXPLAIN shows how the database correctly treats the NULL
literal as a comparison. Jones Jimmy 401
Explanation
---------------------------------------------------------------------------------------------------------------------------------------------
. . . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an all-rows scan with a
condition of ("(DLM.Employee.dept# <> NULL) AND ((DLM.Employee.dept# <> 401) AND
DLM.Employee.dept# <> 403 ))") into Spool 1 (group_amps), which is built locally on the AMPs.
. . . .
Three Versions of NOT IN
SELECT * SELECT *
FROM Employee FROM Employee
WHERE First_Name NOT IN ('alan', 'allen'); WHERE First_Name <> 'alan'
AND First_Name <> 'allen';
SELECT *
FROM Employee
WHERE NOT (First_Name = 'alan' All three return the explain
OR First_Name = 'allen'); shown below.
Explanation
---------------------------------------------------------------------------
. . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an
all-rows scan with a condition of ("(DLM.Employee.first_name <>
'allen ') AND (DLM.Employee.first_name <> 'alan ')") into Spool 1
(group_amps), which is built locally on the AMPs. The size of
Spool 1 is estimated with no confidence to be 10 rows (520 bytes).
The estimated time for this step is 0.02 seconds.
. . .
Incorrect Sequencing of the BETWEEN
The optimizer rewrites the previous query to the Brown Allen 801
following.
Brown ? 567
The EXPLAIN of the previous query illustrates how the Employee Table
optimizer is aware of the unsatisfiable condition. Last First Dept#
Name Name
Only a quick PI access is attempted with an
unsatisfiable condition. Brown Alan 401
The optimizer never estimates 0 rows, so the EXPLAIN Brown Allen 801
showing the 1 row can be ignored. Brown ? 567
Smith Mary ?
SELECT *
FROM Employee Jones Jimmy 401
Explanation
----------------------------------------------------------------------------------------------------------------------------------------------
1) First, we do a single-AMP RETRIEVE step from DLM.Employee by way of the primary index
"DLM.Employee.last_name = _LATIN '010000001800000001E0'XC" with unsatisfiable conditions
into Spool 1 (one-amp), which is built locally on that AMP. The size of Spool 1 is estimated with
high confidence to be 1 row (52 bytes). The estimated time for this step is 0.00 seconds.
-> The contents of Spool 1 are sent back to the user as the result of statement 1. The total
estimated time is 0.00 seconds..
Unsatisfiable BETWEEN with AND
Residual
Employee Table
Since all AND'ed conditions must evaluate true for
Last First Dept#
projection, this condition is also unsatisfiable. Name Name
Explanation
---------------------------------------------------------------------------
1) First, we do a single-AMP RETRIEVE step from DLM.Employee by way
of the primary index "DLM.Employee.last_name = _LATIN
'01000000180000000180'XC" with unsatisfiable conditions into Spool
1 (one-amp), which is built locally on that AMP. The size of
Spool 1 is estimated with high confidence to be 1 row (52 bytes).
The estimated time for this step is 0.00 seconds.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.00 seconds.
Unsatisfiable BETWEEN with OR
Residual
Unsatisfiable conditions combined with OR need
only satisfy the OR condition. Employee Table
SELECT * Last First Dept#
Name Name
FROM Employee
WHERE Dept# BETWEEN 567 AND 401
OR Last_Name = 'brown'; Brown Alan 401
Explanation
-------------------------------------------------------------------------------------------------------------------------
. . . . . . .
3) We do an all-AMPs RETRIEVE step from DLM.Employee by way of an all-rows scan with a
condition of ("DLM.Employee.last_name = 'brown '") into Spool 1 (group_amps), which is built
locally on the AMPs. The size of Spool 1 is estimated with no confidence to be 4 rows (340
bytes). The estimated time for this step is 0.02 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved in processing the
request.
-> The contents of Spool 1 are sent back to the user as the result of statement 1. The total
estimated time is 0.02 seconds.
Precedence of Operators
Evaluation Precedence:
1. Parenthesis evaluated first
2. NOT operators
3. AND operators
4. OR operators
5. Operators of equal precedence evaluated from left to right
Operators =, <>, <=, >=, <, >, IN, NOT IN and BETWEEN can be used as
qualifiers.
All conditions found of the WHERE clause must be satisfied for results
to be projected.
All AND'ed conditions in a list must evaluate true.
Only one condition of an OR'ed list need evaluate true.
Parentheses can be used to (reorder an) order of operations.
NULL, when used in a condition, evaluates unknown.
An EXPLAIN of a query can reveal the optimizer's rewrite and provide a
better understanding of the query.
BETWEEN is inclusive when used to qualify on a range of values.
IN, and NOT IN lists can be used as a short cut to replace long
AND/OR linked conditions.
Module 3: Review Questions
True or False:
1) List last names, department numbers for employee in department 301, 401,
and 501.
2) Project the last names of employees whose salary is greater than or equal
to $28,078.
5) Modify #4 to show only those whose salary amounts are between $50,000
and $60,000.