• Tidak ada hasil yang ditemukan

Filtering on Multiple Conditions

You can combine multiple conditions with boolean operators, such as “AND,”

OR,” or “AND NOT” between them in order to filter using multiple criteria in the WHERE clause.

Clauses with OR between them will jointly evaluate to TRUE, meaning the row will be returned, if any of the clauses are TRUE. Clauses with AND between them will only evaluate to TRUE in combination if all of the clauses evaluate to TRUE. Otherwise, the row will not be returned. Remember that NOT flips the following boolean value to its opposite (TRUE becomes FALSE, and vice versa). See Table 3.2.

Table 3.2 CONDITION 1

EVALUATES TO BOOLEAN

OPERATOR CONDITION 2

EVALUATES TO ROW RETURNED?

TRUE OR FALSE TRUE

TRUE OR TRUE TRUE

FALSE OR FALSE FALSE

TRUE AND FALSE FALSE

TRUE AND TRUE TRUE

TRUE AND NOT FALSE TRUE

Table 3.1

MARKET_

DATE

CUSTOMER_

ID VENDOR_ID

PRODUCT_

ID QUANTITY PRICE

CONDITION:

CUSTOMER_

ID = 4

2019-03-02 3 4 4 8.4 16.80 FALSE

2019-03-02 1 1 11 1.7 20.40 FALSE

2019-03-02 4 4 9 1.4 2.80 TRUE

2019-03-02 4 8 4 2.0 8.00 TRUE

2019-03-09 5 9 7 1.0 16.00 FALSE

2019-03-09 4 1 10 1.0 5.50 TRUE

2019-03-09 4 4 9 9.9 19.80 TRUE

2019-03-09 4 7 12 2.0 6.00 TRUE

2019-03-09 4 7 13 0.3 1.72 TRUE

2019-03-16 3 4 9 5.5 11.00 FALSE

2019-03-16 3 9 8 1.0 18.00 FALSE

So if the WHERE clause lists two conditions with OR between them, like

WHERE customer_id = 3 OR customer_id = 4,” then each condition will be evaluated for each row, and rows where the customer_id is either 3 or 4 (either condition is met) will be returned, as shown in Table 3.3 (some columns have been removed for readability).

Because there is an OR between the two conditions, only one of the conditions has to evaluate to TRUE in order for a row to be returned.

In fact, if there is a long list of conditions, with OR between all of them, only one condition in the entire list has to evaluate to TRUE per row in order for the row to be returned, because it can be read as “Either [Condition 1] is TRUE OR [Condition 2] is TRUE OR [Condition 3] is TRUE,” etc. So, only if all items in the list of “OR conditions” evaluate to FALSE is a row not returned.

Table 3.3

MARKET_

DATE

CUSTOMER _ID

VENDOR _ID PRICE

CONDITION:

CUSTOMER_

ID = 3 OR

CONDITION:

CUSTOMER_

ID = 4

ROW RETURNED?

2019-03-02 3 4 16.80 TRUE OR FALSE TRUE

2019-03-02 1 1 20.40 FALSE OR FALSE FALSE

2019-03-02 4 4 2.80 FALSE OR TRUE TRUE

2019-03-02 4 8 8.00 FALSE OR TRUE TRUE

2019-03-09 5 9 16.00 FALSE OR FALSE FALSE

2019-03-09 4 1 5.50 FALSE OR TRUE TRUE

2019-03-09 4 4 19.80 FALSE OR TRUE TRUE

2019-03-09 4 7 6.00 FALSE OR TRUE TRUE

2019-03-09 4 7 1.72 FALSE OR TRUE TRUE

2019-03-16 3 4 11.00 TRUE OR FALSE TRUE

2019-03-16 3 9 18.00 TRUE OR FALSE TRUE

FALSE AND NOT FALSE FALSE

FALSE OR NOT FALSE TRUE

Here is a query containing the conditions illustrated in Table 3.3 in the WHERE clause, and in Figure 3.3, you can see the actual output:

SELECT

market_date, customer_id, vendor_id, product_id, quantity,

quantity * cost_to_customer_per_qty AS price FROM farmers_market.customer_purchases

WHERE customer_id = 3 OR customer_id = 4

ORDER BY market_date, customer_id, vendor_id, product_id

What would happen if the WHERE clause condition were “customer_id = 3 AND customer_id = 4”? Let’s use the same table setup to illustrate what each condition evaluates to for each row. See Table 3.4.

Figure 3.3  

Table 3.4

MARKET_

DATE

CUSTOMER _ID

VENDOR _ID PRICE

CONDITION:

CUSTOMER_

ID = 3 AND

CONDITION:

CUSTOMER_

ID = 4

ROW RETURNED?

2019-03-02 3 4 16.80 TRUE AND FALSE FALSE

2019-03-02 1 1 20.40 FALSE AND FALSE FALSE

2019-03-02 4 4 2.80 FALSE AND TRUE FALSE

2019-03-02 4 8 8.00 FALSE AND TRUE FALSE

2019-03-09 5 9 16.00 FALSE AND FALSE FALSE

The correct way to read a query with the conditional statement “WHERE cus- tomer_id = 3 AND customer_id = 4” is “Return each row where the customer ID is 3 and the customer ID is 4.” But there is only a single customer_id value per row, so it’s impossible for the customer_id to be both 3 and 4 at the same time, therefore no rows are returned!

Some people make the mistake of reading the logical AND operator the way we might request in English, “Give me all of the rows with customer IDs 3 and 4,” when what we really mean by that phrase is “Give me all of the rows where the customer ID is either 3 or 4,” which would require an OR operator in SQL.

When the AND operator is used, all of the conditions with AND between them must evaluate to TRUE for a row in order for that row to be returned in the query results.

One example where you could use AND in a WHERE clause referring to only a single column is when you want to return rows with a range of values. If someone requests “Give me all of the rows with a customer ID greater than 3 and less than or equal to 5,” the conditions would be written as “WHERE customer_id >

3 AND customer_id <= 5,” and would evaluate as shown in Table 3.5.

Because of the AND, both conditions must evaluate to TRUE in order for a row to be returned.

Let’s try it in SQL, and see the output in Figure 3.4:

SELECT

market_date, customer_id, vendor_id, product_id,

2019-03-09 4 4 19.80 FALSE AND TRUE FALSE

2019-03-09 4 7 6.00 FALSE AND TRUE FALSE

2019-03-09 4 7 1.72 FALSE AND TRUE FALSE

2019-03-16 3 4 11.00 TRUE AND FALSE FALSE

2019-03-16 3 9 18.00 TRUE AND FALSE FALSE

quantity,

quantity * cost_to_customer_per_qty AS price FROM farmers_market.customer_purchases

WHERE customer_id > 3 AND customer_id <= 5

ORDER BY market_date, customer_id, vendor_id, product_id

You can combine multiple AND, OR, and NOT conditions, and control in which order they get evaluated, by using parentheses the same way you would in an algebraic expression to specify the order of operations. The conditions inside the parentheses get evaluated first.

Figure 3.4   Table 3.5

MARKET_

DATE

CUSTOMER _ID

VENDOR _ID PRICE

CONDITION:

CUSTOMER_

ID > 3 AND

CONDITION:

CUSTOMER_

ID <= 5

ROW RETURNED?

2019-03-02 3 4 16.80 FALSE AND TRUE FALSE

2019-03-02 1 1 20.40 FALSE AND TRUE FALSE

2019-03-02 4 4 2.80 TRUE AND TRUE TRUE

2019-03-02 4 8 8.00 TRUE AND TRUE TRUE

2019-03-09 5 9 16.00 TRUE AND TRUE TRUE

2019-03-09 4 1 5.50 TRUE AND TRUE TRUE

2019-03-09 4 4 19.80 TRUE AND TRUE TRUE

2019-03-09 4 7 6.00 TRUE AND TRUE TRUE

2019-03-09 4 7 1.72 TRUE AND TRUE TRUE

2019-03-16 3 4 11.00 FALSE AND TRUE FALSE

2019-03-16 3 9 18.00 FALSE AND TRUE FALSE

product_name

FROM farmers_market.product WHERE

product_id = 10 OR (product_id > 3 AND product_id < 8)

Now look at this query and its output in Figure 3.6:

SELECT

product_id, product_name

FROM farmers_market.product WHERE

(product_id = 10 OR product_id > 3) AND product_id < 8

When the product ID is 10, the WHERE clause in the first query is evaluated as:

TRUE OR (TRUE AND FALSE) = TRUE OR (FALSE) = TRUE and the WHERE clause in the second query is evaluated as:

(TRUE OR TRUE) AND FALSE = (TRUE) AND FALSE = FALSE Figure 3.5  

Figure 3.6  

Since the OR statement evaluates to TRUE if any of the conditions are TRUE, but the AND statement only evaluates to TRUE if all of the conditions are true, the row with a product_id value of 10 is only returned by the first query.