Comparison Operators: FALSE Are Self-Explanatory, But What Is Unknown ?
Comparison Operators: FALSE Are Self-Explanatory, But What Is Unknown ?
True to their name, comparison operators compare expressions and return one of three
values: TRUE , FALSE , or Unknown . Wait a minute! Unknown ? TRUE and
FALSE are self-explanatory, but what is Unknown ?
To understand how you could get an Unknown , you need to know a little about the
concept of NULL . In database terms NULL is the absence of data in a field. It does
not mean a column has a zero or a blank in it. A zero or a blank is a value. NULL
means nothing is in that field. If you make a comparison like Field = 9 and the only
value for Field is NULL , the comparison will come back Unknown . Because
Unknown is an uncomfortable condition, most flavors of SQL change Unknown to
FALSE and provide a special operator, IS NULL , to test for a NULL condition.
Here's an example of NULL : Suppose an entry in the PRICE table does not contain
a value for WHOLESALE . The results of a query might look like this:
INPUT:
OUTPUT:
ITEM WHOLESALE
TOMATOES .34
POTATOES .51
BANANAS .67
TURNIPS .45
CHEESE .89
APPLES .23
ORANGES
Notice that nothing is printed out in the WHOLESALE field position for oranges.
The value for the field WHOLESALE for oranges is NULL . The NULL is
noticeable in this case because it is in a numeric column. However, if the NULL
appeared in the ITEM column, it would be impossible to tell the difference between
NULL and a blank.
Try to find the NULL :
INPUT/OUTPUT:
SQL> SELECT *
2 FROM PRICE
3 WHERE WHOLESALE IS NULL;
ITEM WHOLESALE
ORANGES
ANALYSIS:
As you can see by the output, ORANGES is the only item whose value for
WHOLESALE is NULL or does not contain a value. What if you use the equal sign (
= ) instead?
INPUT/OUTPUT:
SQL> SELECT *
FROM PRICE
WHERE WHOLESALE = NULL;
no rows selected
ANALYSIS:
You didn't find anything because the comparison WHOLESALE = NULL returned a
FALSE - the result was unknown. It would be more appropriate to use an IS NULL
instead of = , changing the WHERE statement to WHERE WHOLESALE IS
NULL . In this case you would get all the rows where a NULL existed.
This example also illustrates both the use of the most common comparison operator, the
equal sign ( = ), and the playground of all comparison operators, the WHERE clause.
You already know about the WHERE clause, so here's a brief look at the equal sign.
Equal (=)
Earlier today you saw how some implementations of SQL use the equal sign in the
SELECT clause to assign an alias. In the WHERE clause, the equal sign is the most
commonly used comparison operator. Used alone, the equal sign is a very convenient
way of selecting one value out of many. Try this:
INPUT:
OUTPUT:
Let's find JD's row. (On a short list this task appears trivial, but you may have more
friends than we do--or you may have a list with thousands of records.)
INPUT/OUTPUT:
INPUT/OUTPUT:
NOTE: Here you see that = can pull in multiple records. Notice that ZIP is
blank on the second record. ZIP is a character field, and in this
particular record the NULL demonstrates that a NULL in a character field
is impossible to differentiate from a blank field.
INPUT/OUTPUT:
FIRSTNAME
BUD
1 row selected.
INPUT/OUTPUT:
no rows selected.
ANALYSIS:
Even though SQL syntax is not case sensitive, data is. Most companies prefer to store
data in uppercase to provide data consistency. You should always store data either in
all uppercase or in all lowercase. Mixing case creates difficulties when you try to
retrieve accurate data.
Greater Than (>) and Greater Than or Equal To (>=)
INPUT:
SQL> SELECT *
FROM FRIENDS
WHERE AREACODE > 300;
OUTPUT:
ANALYSIS:
This example found all the area codes greater than (but not including) 300 . To include
300 , type this:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE AREACODE >= 300;
ANALYSIS:
With this change you get area codes starting at 300 and going up. You could achieve
the same results with the statement AREACODE > 299 .
NOTE: Notice that no quotes surround 300 in this SQL statement. Number-
defined fieldsnumber-defined fields do not require quotes.
As you might expect, these comparison operators work the same way as > and >=
work,
only in reverse:
INPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE STATE < 'LA';
OUTPUT:
NOTE: How did STATE get changed to ST ? Because the column has only
two characters, the column name is shortened to two characters in the
returned rows. If the column name had been COWS , it would come out CO .
The widths of AREACODE and PHONE are wider than their column
names, so they are not truncated.
ANALYSIS:
Wait a minute. Did you just use < on a character field? Of course you did. You can use
any of these operators on any data type. The result varies by data type. For example, use
lowercase in the following state search:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE STATE < 'la';
ANALYSIS:
Uppercase is usually sorted before lowercase; therefore, the uppercase codes returned
are less than 'la' . Again, to be safe, check your implementation.
TIP: To be sure of how these operators will behave, check your language
tables. Most PC implementations use the ASCII tables. Some other platforms
use EBCDIC.
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE STATE <= 'LA';
When you need to find everything except for certain data, use the inequality symbol,
which can be either < > or != , depending on your SQL implementation. For example,
to find everyone who is not AL , type this:
INPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE FIRSTNAME <> 'AL';
OUTPUT:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE STATE != 'CA';
NOTE: Notice that both symbols, <> and != , can express "not equals."
Character Operators
You can use character operators to manipulate the way character strings are
represented, both in the output of data and in the process of placing conditions on data
to be retrieved. This section describes two character operators: the LIKE operator and
the || operator, which conveys the concept of character concatenation.
LIKE
I Want to Be Like
What if you wanted to select parts of a database that fit a pattern but weren't quite exact
matches? You could use the equal sign and run through all the possible cases, but
that process would be boring and time-consuming. Instead, you could use LIKE .
Consider the following:
INPUT:
OUTPUT:
APPENDIX MID-STOMACH 1
ADAMS APPLE THROAT 2
HEART CHEST 3
SPINE BACK 4
ANVIL EAR 5
KIDNEY MID-BACK 6
How can you find all the parts located in the back? A quick visual inspection of this
simple table shows that it has two parts, but unfortunately the locations have slightly
different names. Try this:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM PARTS
3 WHERE LOCATION LIKE '%BACK%';
SPINE BACK 4
KIDNEY MID-BACK 6
ANALYSIS:
You can see the use of the percent sign ( % ) in the statement after LIKE . When used
inside a LIKE expression, % is a wildcard. What you asked for was any occurrence of
BACK in the column location. If you queried
INPUT:
SQL> SELECT *
FROM PARTS
WHERE LOCATION LIKE 'BACK%';
SPINE BACK 4
If you queried
INPUT:
SQL> SELECT *
FROM PARTS
WHERE NAME LIKE 'A%';
APPENDIX MID-STOMACH 1
ADAMS APPLE THROAT 2
ANVIL EAR 5
INPUT/OUTPUT:
SQL> SELECT *
FROM PARTS
WHERE NAME LIKE 'a%';
no rows selected
ANALYSIS:
What if you want to find data that matches all but one character in a certain pattern?
In this case you could use a different type of wildcard: the underscore.
Underscore (_)
The underscore is the single-character wildcard. Using a modified version of the table
FRIENDS , type this:
INPUT:
To find all the records where STATE starts with C , type the following:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE STATE LIKE 'C_';
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE PHONE LIKE'555-6_6_';
SQL> SELECT *
2 FROM FRIENDS
3 WHERE PHONE LIKE '555-6%';
Notice that the results are identical. These two wildcards can be combined. The next
example finds all records with L as the second character:
INPUT/OUTPUT:
SQL> SELECT *
2 FROM FRIENDS
3 WHERE FIRSTNAME LIKE '_L%';
Concatenation (||)
The || (double pipe) symbol concatenates two strings. Try this:
INPUT:
ENTIRENAME
AL BUNDY
AL MEZA
BUD MERRICK
JD MAST
FERRIS BULHER
ALTON PERKINS
SIR BOSS
7 rows selected.
ANALYSIS:
Notice that || is used instead of + . If you use + to try to concatenate the strings, the
SQL interpreter used for this example (Personal Oracle7) returns the following error:
INPUT/OUTPUT:
ERROR:
ORA-01722: invalid number
It is looking for two numbers to add and throws the error invalid number when it
doesn't find any.
INPUT/OUTPUT:
BUNDY, AL
MEZA, AL
MERRICK, BUD
MAST, JD
BULHER, FERRIS
PERKINS , ALTON
BOSS, SIR
7 rows selected.
ANALYSIS:
This statement inserted a comma between the last name and the first name.
NOTE: Notice the extra spaces between the first name and the last name in
these examples. These spaces are actually part of the data. With certain
data types, spaces are right-padded to values less than the total length
allocated for a field.
So far you have performed the comparisons one at a time. That method is fine for some
problems, but what if you need to find all the people at work with last names starting
with P who have less than three days of vacation time?