In today’s lesson you’re going to learn more about filtering results returned from your queries using the WHERE clause using Boolean logic.

The objectives of today’s lesson are to:

- Learn to use more than one compare condition at a time using Boolean logic
- Comprehensive example with Select, Where, and Order By

**Important!** Please follow along and do the examples in your database. If you haven’t already done so, sign up for my Guide to Getting Started with SQL Server. You get instructions on how to install the free tools and sample database.

**Using Multiple Conditions**

In previous lesson’s we learned how the where clause is used filter out any records where the where condition is FALSE. Did you also know you can also string conditions together to create more complex conditions? To do so we can use the AND, OR, and NOT operators.

These three operators are used for the most common aspects of Boolean logic. Regardless of which operator is used the result always boils down to one of two outcomes: TRUE or FALSE.

Where clauses become really interesting when we consider combining more than one field to filter a result. For instance, using our sample database as an example, we may want to find large purchase orders, such as those with an order quantity greater than 10 and unit price greater than $5.00. This could be written as

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice FROM Purchasing.PurchaseOrderDetail WHERE UnitPrice > 5.00 AND OrderQty > 10

Records are only included when both conditions are TRUE.

Now that we know how to write more complicated conditions, let’s learn more about the various Boolean operators. We’ll start with AND.

**Boolean AND Operator**

The AND operator returns a TRUE only if all conditions are also TRUE. The following truth table shows all combinations of values the condition (A AND B).

Condition A | Condition B | Result |

TRUE | TRUE | TRUE |

TRUE | FALSE | FALSE |

FALSE | TRUE | FALSE |

FALSE | FALSE | FALSE |

In SQL we can string a where clause together using to test multiple fields. For instance if you’re looking for customers from Midland, TX you could write

WHERE State = 'TX' AND City = 'Midland'

You can also use the AND operator to create range condition, much like we do with BETWEEN.

Using our previous example of wanting to find TotalPrices that fall within $100.00 and $200.00 dollars we would write

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice, UnitPrice * OrderQty AS TotalPrice FROM Purchasing.PurchaseOrderDetail WHERE UnitPrice * OrderQty >= 100 AND UnitPrice * OrderQty <= 200

This returns the same result as

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice, UnitPrice * OrderQty AS TotalPrice FROM Purchasing.PurchaseOrderDetail WHERE UnitPrice * OrderQty BETWEEN 100 AND 200

**Tip!** Keep in mind that Boolean logic AND doesn’t completely translate to English “and.” For instance If were to say Search for all customers in the states of Florida *and* Georgia, you would most likely know I meant find all customer from either Florida or Georgia. You wouldn’t think I meant for you to find all customers that are in *both* Florida and Georgia.

**Boolean OR Operator**

The OR operator returns a TRUE when one or more conditions are also TRUE. Here is the Truth table for the OR operator. You’ll see that in every case one of the conditions is true, so is the end result.

Condition A | Condition B | Result |

TRUE | TRUE | TRUE |

TRUE | FALSE | TRUE |

FALSE | TRUE | TRUE |

FALSE | FALSE | FALSE |

The where clause to select all Customers from either Texas or Florida is

WHERE State = 'FL' OR State = 'TX'

Multiple OR clauses can be connected together to behave similar to the IN statement. In this manner they act as a membership condition.

To find all employees with one of three job titles we can write

SELECT NationalIDNumber, BirthDate, JobTitle FROM HumanResources.Employee WHERE JobTitle = 'Design Engineer' OR JobTitle = 'Stocker' OR JobTitle = 'Buyer'

This is the same as this

SELECT NationalIDNumber, BirthDate, JobTitle FROM HumanResources.Employee WHERE JobTitle IN ('Design Engineer', 'Stocker', 'Buyer')

**Boolean NOT Operator**

Condition A | Result |

TRUE | FALSE |

FALSE | TRUE |

The not operator takes a condition and changes it to the opposite. So given TRUE, the NOT operator changes it to FALSE. Some examples of expressions using the NOT statement include:

- NOT IN (‘TX’, ‘FL’) – Accept every state except Texas and Florida
- NOT IN (‘CEO’, ‘Owner’, ‘President’) – Accept everyone that isn’t an owner.

The NOT statement can also be used in combination with AND and OR. However, to explain this, we first need to understand which order the conditions are evaluated and how to group them together.

In other words, we need to learn about parenthesis and used them much in the same way you would use them with adding and multiplying numbers.

**Combining Boolean Operators**

The order Boolean operators are executed is important and isn’t arbitrary. Much like in arithmetic, where multiplication occurs before additions, in Boolean operators, AND is evaluated before OR.

Can you tell what’s wrong in this photo? What did they really mean?

In English they are trying to say that you can have your choice of soup with either a spring roll or crab Rangoon, but since the AND condition is evaluated first, the SQL engine sees these choices:

- Hot & Sour soup
- Wonton Soup
- Egg Drop Soup and Spring Roll
- Crab Rangoon

You can also use parenthesis. The expression inside of the parenthesis is evaluated first.

Let’s say you wanted to return all customers who are not owners. How could we do this?

ContactTitle = 'CEO' OR ContactTitle = 'Owner' OR ContactTitle = 'President'

Now, to get those that aren’t owners we need to reverse the logic as

NOT (ContactTitle = 'CEO' OR ContactTitle = 'Owner' OR ContactTitle = 'President')

Notice the use of parenthesis, the condition within the parenthesis are evaluated first, then the NOT condition second.

**Comprehensive Example**

Suppose we need to find all large Purchase Order details entries. If we consider a large Order to be one where the Quantity > 100 or the UnitPrice > 10 and we want to order them by the total price. How would we go about this? Lets try:

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice, UnitPrice * OrderQty AS TotalPrice FROM Purchasing.PurchaseOrderDetail WHERE (UnitPrice > 10 OR OrderQty > 100) ORDER BY TotalPrice

Now we could refine this further by then asserting that the TotalPrice is greater than 1000.

The modified query is

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice, UnitPrice * OrderQty AS TotalPrice FROM Purchasing.PurchaseOrderDetail WHERE (UnitPrice > 10 OR OrderQty > 100) AND UnitPrice * OrderQty >= 1000 ORDER BY TotalPrice

I added the parenthesis around the OR clauses so they would be evaluated before the AND; otherwise the statement would have a different result.

One final comment: You notice that I used the column alias TotalPrice in the ORDER BY clause, but didn’t use it in the WHERE clause. This is due to a limitation in SQL Server. Some versions, such as SQLite would allow you to write the following, which is prohibited in SQL Server:

SELECT PurchaseOrderDetailID, ProductID, OrderQty, UnitPrice, UnitPrice * OrderQty AS TotalPrice FROM Purchasing.PurchaseOrderDetail WHERE (UnitPrice > 10 OR OrderQty > 100) AND TotalPrice >= 1000 ORDER BY TotalPrice

**Exercises**

It’s important to practice! Use the sample database to answer these questions.

- Find all single female employees
- Find all employees that have 40 to 80 hours of vacation time.
- Find all employees that have 40 to 80 hours of vacation time or 40 to 80 hours of sick time. Also, the employees should be male.

Congratulations! You just learned how to use multiple conditions to create more sophisticated filtering conditions. More tutorials are to follow! Remember! I want to remind you all that if you have other questions you want answered, then post a comment or tweet me. I’m here to help you. What other topics would you like to know more about?

A co-worker wondered if the parenthesis are required when there is just two clauses separated by an OR. The statement in question was:

SELECT PurchaseOrderDetailID,

ProductID,

OrderQty,

UnitPrice,

UnitPrice * OrderQty AS TotalPrice

FROM Purchasing.PurchaseOrderDetail

WHERE (UnitPrice > 10

OR OrderQty > 100)

To answer the question they aren’t required syntax. The statement would evaluate the same whether the parenthesis were used or not.

Hi Kris,

On the question #3, I compared “gender” first and you did it last. I should just follow what the question is asking–correct?

Thanks

Maria

Hi,

The order doesn’t matter as long as you use parenthesis to separate the OR clause.

`WHERE Gender = 'M' AND`

(VacationHours BETWEEN 40 and 80 OR

SickLeaveHours BETWEEN 40 AND 80)

Is the Same as

`WHERE (VacationHours BETWEEN 40 and 80 OR`

SickLeaveHours BETWEEN 40 AND 80) AND

Gender = 'M'

But

`WHERE Gender = 'M' AND`

VacationHours BETWEEN 40 and 80 OR

SickLeaveHours BETWEEN 40 AND 80

Isn’t correct as the AND is be evaluated first. This statement is selecting employees that are Male and have 40 to 80 vacation hours,

or allemployees who have between 40 and 80 sick leave hours.