Combining WHERE ClausesAll the WHERE clauses introduced in Chapter 6, "Filtering Data," filter data using a single criteria. For a greater degree of filter control, MySQL allows you to specify multiple WHERE clauses. These clauses may be used in two ways: as AND clauses or as OR clauses. New Term Operator A special keyword used to join or change clauses within a WHERE clause. Also known as logical operators. Using the AND OperatorTo filter by more than one column, you use the AND operator to append conditions to your WHERE clause. The following code demonstrates this: • Input SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 1003 AND prod_price <= 10; • Analysis The preceding SQL statement retrieves the product name and price for all products made by vendor 1003 as long as the price is 10 or less. The WHERE clause in this SELECT statement is made up of two conditions, and the keyword AND is used to join them. AND instructs the DBMS to return only rows that meet all the conditions specified. If a product is made by vendor 1003 but it costs more than 10, it is not retrieved. Similarly, products that cost less than 10 that are made by a vendor other than the one specified are not retrieved. The output generated by this SQL statement is as follows: • Output +---------+------------+----------------+ | prod_id | prod_price | prod_name | +---------+------------+----------------+ | FB | 10.00 | Bird seed | | FC | 2.50 | Carrots | | SLING | 4.49 | Sling | | TNT1 | 2.50 | TNT (1 stick) | | TNT2 | 10.00 | TNT (5 sticks) | +---------+------------+----------------+ New Term AND A keyword used in a WHERE clause to specify that only rows matching all the specified conditions should be retrieved. The example just used contained a single AND clause and was thus made up of two filter conditions. Additional filter conditions could be used as well, each seperated by an AND keyword. Using the OR OperatorThe OR operator is exactly the opposite of AND. The OR operator instructs MySQL to retrieve rows that match either condition. Look at the following SELECT statement: • Input SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR vend_id = 1003; • Analysis The preceding SQL statement retrieves the product name and price for any products made by either of the two specified vendors. The OR operator tells the DBMS to match either condition, not both. If an AND operator would have been used here, no data would be returned (it would have created a WHERE clause that could never be matched). The output generated by this SQL statement is as follows: • Output +----------------+------------+ | prod_name | prod_price | +----------------+------------+ | Detonator | 13.00 | | Bird seed | 10.00 | | Carrots | 2.50 | | Fuses | 3.42 | | Oil can | 8.99 | | Safe | 50.00 | | Sling | 4.49 | | TNT (1 stick) | 2.50 | | TNT (5 sticks) | 10.00 | +----------------+------------+ New Term OR A keyword used in a WHERE clause to specify that any rows matching either of the specified conditions should be retrieved. Understanding Order of EvaluationWHERE clauses can contain any number of AND and OR operators. Combining the two enables you to perform sophisticated and complex filtering. But combining AND and OR operators presents an interesting problem. To demonstrate this, look at an example. You need a list of all products costing 10 or more made by vendors 1002 and 1003. The following SELECT statement uses a combination of AND and OR operators to build a WHERE clause: • Input SELECT prod_name, prod_price FROM products WHERE vend_id = 1002 OR vend_id = 1003 AND prod_price >= 10; • Output +----------------+------------+ | prod_name | prod_price | +----------------+------------+ | Detonator | 13.00 | | Bird seed | 10.00 | | Fuses | 3.42 | | Oil can | 8.99 | | Safe | 50.00 | | TNT (5 sticks) | 10.00 | +----------------+------------+ • Analysis Look at the previously listed results. Two of the rows returned have prices less than 10so, obviously, the rows were not filtered as intended. Why did this happen? The answer is the order of evaluation. SQL (like most languages) processes AND operators before OR operators. When SQL sees the preceding WHERE clause, it reads products made by vendor 1002 regardless of price, and any products costing 10 or more made by vendor 1003. In other words, because AND ranks higher in the order of evaluation, the wrong operators were joined together. The solution to this problem is to use parentheses to explicitly group related operators. Take a look at the following SELECT statement and output: • Input SELECT prod_name, prod_price FROM products WHERE (vend_id = 1002 OR vend_id = 1003) AND prod_price >= 10; • Output +----------------+------------+ | prod_name | prod_price | +----------------+------------+ | Detonator | 13.00 | | Bird seed | 10.00 | | Safe | 50.00 | | TNT (5 sticks) | 10.00 | +----------------+------------+ • Analysis The only difference between this SELECT statement and the earlier one is that, in this statement, the first two WHERE clause conditions are enclosed within parentheses. As parentheses have a higher order of evaluation than either AND or OR operators, the DBMS first filters the OR condition within those parentheses. The SQL statement then becomes any products made by either vendor 1002 or vendor 1003 costing 10 or greater, which is exactly what you want. Tip Using Parentheses in WHERE Clauses Whenever you write WHERE clauses that use both AND and OR operators, use parentheses to explicitly group operators. Don't ever rely on the default evaluation order, even if it is exactly what you want. There is no downside to using parentheses, and you are always better off eliminating any ambiguity. |