The WHERE conditions filter the output of the FROM
clause and restrict the returned rows in the result set. The conditions
can refer to the data within the tables, expressions, built-in SQL
Server scalar functions, other queries, or user-defined functions. The WHERE conditions can also use several possible comparison operators and wildcards, as listed in Table 1. In addition, you can combine multiple WHERE conditions using Boolean AND, OR, and NOT operators.
Table 1 Standard Comparison Operators
Equals |
= |
Quantity = 12 |
Greater than |
> |
Quantity > 12 |
Greater than or equal to |
>= |
Quantity >= 12 |
Less than |
< |
Quantity < 12 |
Less than or equal to |
<= |
Quantity<= 12 |
Not equal to |
<> , != |
Quantity <> 12 , Quantity != 12 |
Not less than |
!< |
Quantity !< 12 |
Not greater than |
!> |
Quantity !> 12 |
Best Practice
To improve the performance of a
client/server database, let the database engine do the work of
restricting the rows returned, rather than make the client application
wade through unnecessary data.
Caution
The comparison operators that include an exclamation point are not ANSI standard SQL. <> is portable; != is not.
Best Practice
The best way to find a thing is to
look for it, rather than to first eliminate everything it isn't. It's
easier to locate a business in a city than it is to prove that the
business doesn't exist. The same is true of database searches. Proving
that a row meets a condition is faster than first eliminating every row
that doesn't meet that condition. In general (but not always),
restating a negative WHERE condition as a positive condition improves performance.
Using the BETWEEN Search Condition
The BETWEEN search condition tests for values within a range. The range can be deceiving, however, because it is inclusive. For example, BETWEEN 1 and 10 would be true for 1 and 10. When using the BETWEEN search condition, the first condition must be less than the latter value because in actuality, the BETWEEN search condition is shorthand for “greater than or equal to the first value, and less than or equal to the second value.”
In this example, the BETWEEN selects all the work orders with a quantity greater than 9 and less than 20:
USE AdventureWorks;
SELECT WorkOrderID
FROM Production.WorkOrder
WHERE OrderQty BETWEEN 10 and 19
Caution
The BETWEEN search condition is commonly used with dates. However, BETWEEN
without a time looks for the beginning of the final day, or with a time
rounds up the final millisecond to possibly include 12:00:00.000 of the
next day. The solution is to use the following:
WHERE Col >= StartDay AND Col < Ending Day + 1
For example,
WHERE SalesDate >= ‘6/1/2008’ AND SalesDate < ‘7/1/2008'
Comparing with a List
The WHERE condition can compare the test value against the values in a list using IN, SOME, ANY, or ALL. Each operator can also be mixed with a NOT to reverse the condition.
Algebra Actually Is Useful
As much fun as algebra class was,
although you thought algebra might improve your logical minds, few of
you believe you would actually use algebra in your chosen profession.
Enter the SQL WHERE clause.
Here's the problem: If you apply a function to the test column in the WHERE clause, then SQL Server is forced to calculate that function on every row before it can filter the WHERE clause. This is a sure setup for “Gee, I don't know, it worked OK on my notebook” syndrome.
For a simple example, assume there's an index on Coll. The following WHERE clause generates an unnecessary scan, reading every row, as every column is modified and then compared to 130:
SELECT Col2, Col3
FROM table
WHERE Col11 + 30 = 130;
Algebra to the rescue. Somehow figure out a way to move that function to the parameter on the right side of the = and off the column, so that the column on the left side is unencumbered by any calculation or functions:
SELECT Col2, Col3
FROM table
WHERE Col11 = 130 – 30;
Now SQL Server can evaluate 130 – 30 and perform a blazingly fast index seek on the rows with 100 in Col1. Although this is a simple example, the principle is true. How you write your WHERE clauses has a significant effect on the performance of your queries.
This is only a small taste of the Query Optimizer and whether WHERE clause expressions are searchable arguments, known as sargs.
SOME and ANY search conditions are functionally similar to IN — all are true if any value in the list is true — with three significant differences:
- SOME and ANY require a subquery. A list of literal values won't do.
- SOME and ANY are used with a mathematical operator (=, >, <, =>, etc.).
- IN, SOME, and ANY function differently when used with a NOT condition.
The AND search condition also requires a true subquery and returns a true when the search condition is true for every value in the list.
IN is similar to the EQUALS comparison operator because it searches for an exact match from a list. If the value is in the list, then the comparison is true.
For instance, if you query the StateProvince table in the
AdventureWorks database providing a list of state or province codes
similar to the following:
USE AdventureWork;
SELECT Name
FROM Person.StateProvince
WHERE StateProvinceCode IN ('NC', ‘WV');
Result:
Name
-----------
North Carolina
West Virginia
Effectively, the IN search condition is the equivalent of multiple EQUALS comparisons ORed together:
USE AdventureWorks;
SELECT Name
FROM Person.StateProvince
WHERE StateProvinceCode = ‘NC'
OR StateProvinceCode = ‘WV';
Result:
Name
-----------
North Carolina
West Virginia
The IN operator may also search for a value in a list of columns. The following example searches for the text ‘Ken in either the FirstName and LastName columns:
USE AdventureWorks;
SELECT FirstName, LastName
FROM Person.Person
WHERE ‘Ken' IN (FirstName, LastName)
Result:
FirstName LastName
-----------------------
Ken Kwok
Ken Meyer
Ken Myer
Ken Myer
Ken Sanchez
Ken Sanchez
You can combine the IN operator with NOT to exclude certain rows. For example, WHERE NOT IN ('NC', ‘WV') would return all rows except those in North Carolina and West Virginia:
USE AdventureWorks;
SELECT StateProvinceCode
FROM Person.StateProvince
WHERE StateProvinceCode NOT IN ('NC', ‘WV');
Abbreviated Result:
StateProviceCode
-----------
AB
AK
AL
AR
AS
AS
. . .
It's difficult to prove a negative, especially when a null value is involved. Because the meaning of null is “unknown,” the value being searched for could be in the list. The following code sample demonstrates how a null in the list makes it impossible to prove that ‘A' is not in the list:
SELECT ‘IN' WHERE ‘A' NOT IN ('B',NULL);
There's no result because the unknown null value might simply be an “A.” Because SQL can't logically prove that “A” is not in the list, the WHERE clause returns a false. Anytime a NOT IN condition is mixed with a null in the list, every row will be evaluated as false.