You can filter your output so you can return only a few records that meet certain criteria.
Introduction
You already know the basic syntax of the select statement and how to retrieve columns from one table in your database, but very often you don’t need all records from a table.
The SQL where clause allows you to filter your results.
This clause introduces certain conditions, like:
quantity < 100price between 100 and 500customer_name = 'John Smith'
Sample Database
The Sakila sample database is a fictitious database designed to represent a DVD rental store. The tables of the database include film, film_category, actor, customer, rental, payment and inventory among others.
Download sakila database file from this link: sakila.db
where
The select statement returns all rows from one or more columns in a table.
To retrieve rows that satisfy a specified condition, you use a where clause.
select <columns>from <table>where <condition>order by <column>;In this syntax,
- You place the
whereclause right after thefromclause of theselectstatement. - The
whereclause uses the condition to filter the rows returned from theselectclause. - The condition is a boolean expression that evaluates to
true,false, or unknown.
The query returns only rows that satisfy the condition in the where clause.
In other words, the query will include only rows that cause the condition to evaluate to true in the result set.
SQLite evaluates the where clause after the from clause, but before the select and order by clause:
If you use column aliases in the select clause, you cannot use them in the where clause.
Besides the select statement, you can use the where clause in the update and delete statement to specify rows to update and delete.
To form the condition in the where clause, you use comparison and logical operators:
| Operator | Description |
|---|---|
= | Equal |
> | Greater than |
< | Less than |
>= | Greater than or equal |
<= | Less than or equal |
<> or != | Not equal |
and | Logical operator AND |
or | Logical operator OR |
in | Return true if a value matches any in a list |
between | Return true if a value is between a range |
like | Return true if a value matches a pattern |
is null | Return true if a value is NULL |
not | Negate the result of other operators |
Tasks
Let’s practice with some examples of using the where clause.
We will use the customer table from the sample database for demonstration.
Find customers whose first name is Jamie:
select first_name, last_namefrom customerwhere first_name = 'JAMIE'| first_name | last_name |
|---|---|
| JAMIE | RICE |
| JAMIE | WAUGH |
Find customers whose first name and last names are “JAMIE” and “RICE”:
select first_name, last_namefrom customerwhere first_name = 'JAMIE' and last_name = 'RICE'| first_name | last_name |
|---|---|
| JAMIE | RICE |
Find the customers whose last name is Rodriguez or first name is Adam:
select first_name, last_namefrom customerwhere last_name = 'RODRIGUEZ' or first_name = 'ADAM'| first_name | last_name |
|---|---|
| LAURA | RODRIGUEZ |
| ADAM | GOOCH |
If you want to find a value in a list of values, you can use the in operator.
Find the customers with first names in the list ANN, ANNE, and ANNIE:
select first_name, last_namefrom customerwhere first_name IN ('ANN', 'ANNE', 'ANNIE')| first_name | last_name |
|---|---|
| ANN | EVANS |
| ANNE | POWELL |
| ANNIE | RUSSELL |
To find a string that matches a specified pattern, you use the like operator.
Find customers whose first names start with the word ANN:
select first_name, last_namefrom customerwhere first_name like 'ANN%'| first_name | last_name |
|---|---|
| ANNA | HILL |
| ANN | EVANS |
| ANNE | POWELL |
| ANNIE | RUSSELL |
| ANNETTE | OLSON |
The % is called a wildcard that matches any string.
The 'ANN%' pattern matches any strings that start with 'ANN'.
Find customers whose first names start with the letter A and contains 3 to 5 characters by using the between operator.
The between operator returns true if a value is in a range of values.
select first_name as name, length(first_name) as name_lengthfrom customerwhere first_name like 'A%' and length(first_name) between 3 and 5order by name_length| name | count |
|---|---|
| AMY | 3 |
| ANN | 3 |
| ANA | 3 |
| ANNA | 4 |
| … | … |
Finds customers whose first names start with Bra and last names are not Motley
select first_name, last_namefrom customerwhere first_name like 'BRA%' and last_name != 'MOTLEY'| first_name | last_name |
|---|---|
| BRANDY | GRAVES |
| BRANDON | HUEY |
| BRAD | MCCURDY |
Note that you can use the != operator and <> operator interchangeably because they are equivalent.
and
A boolean value can have one of three values: true, false, and null.
SQLite uses true and 1 to represent true false and 0 to represent false.
A boolean expression is an expression that evaluates to a boolean value.
For example, the expression 1 = 1 is a boolean expression that evaluates to true:
select 1 = 1 as result| result |
|---|
| 1 |
The 1 in the output indicates the value of true.
The and operator is a logical operator that combines two boolean expressions.
The and operator:
- Returns
trueonly if both expressions aretrue. - It returns
falseif one of the expressions isfalse. - Otherwise, it returns
null.
The following table shows the results of the and operator when combining true, false, and null.
Note that the order of the expressions doesn’t matter, for example, both true and null and null and true will evaluate to null.
| e1 | e2 | e1 and e2 |
|---|---|---|
| True | True | True |
| True | False | False |
| True | Null | Null |
| False | False | False |
| False | Null | False |
| Null | Null | Null |
Ensure the and truth table follows three-valued logic.
For example, check that true and null evaluates to null.
select true and null as result| result |
|---|
| null |
In practice, you often use the and operator in a where clause to ensure that all specified expressions must be true for a row to be included in the result set.
Tasks
We’ll use the film table from the sample database.
Find all films that are not rated PG:
Find the films that have a length greater than 180 and a rental rate less than 1
select title, length, rental_ratefrom filmwhere length > 180 and rental_rate < 1or
The or operator:
- Returns
trueonly if any of the expressions istrue. - It returns
falseif both expressions arefalse. - Otherwise, it returns
null.
The following table shows the results of the or operator when combining true, false, and null.
Note that the order of the expressions doesn’t matter, for example both false or null and null or false will evaluate to null.
| e1 | e2 | e1 or e2 |
|---|---|---|
| True | True | True |
| True | False | True |
| True | Null | True |
| False | False | False |
| False | Null | Null |
| Null | Null | Null |
In practice, you usually use the or operator in a where clause to ensure that either of the specified expressions must be true for a row to be included in the result set.
Find the films that have a rental rate is 0.99 or 2.99
select title, rental_ratefrom filmwhere rental_rate = 0.99 or rental_rate = 2.99in
The in operator returns true if the value is equal to any value in the list such as value1 and value2.
The list of values can be a list of literal values, including numbers and strings.
Functionally, the in operator is equivalent to combining multiple boolean expressions with the or operators:
value = value1 or value = value2 or ...Tasks
Retrieve information about the film with id 1, 2, and 3:
select film_id, titlefrom filmwhere film_id in (1,2,3)The following statement uses the equal (=) and or operators instead of the in operator, which is equivalent to the query above:
select film_id, titlefrom filmwhere film_id = 1 or film_id = 2 or film_id =3The query that uses the in operator is shorter and more readable than the query that uses equal (=) and or operators.
Additionally, SQLite executes the query with the in operator much faster than the same query that uses a list of or operators.
Find the actors on the actor table who have the last name in the list ‘Allen’, ‘Chase’, and ‘Davis’:
select first_name, last_namefrom actorwhere last_name in ('ALLEN', 'CHASE', 'DAVIS')order by first_nameFind payments on the payment table whose payment dates are in a list of dates: 2005-02-15 and 2005-02-16
select payment_id, amount, strftime('%Y-%m-%d', payment_date) as datefrom paymentwhere strftime('%Y-%M-%d', payment_date) in ('2005-02-15', '2005-02-16')To negate the in operator, you use the not in operator.
Retrieve films whose id is not 1, 2, or 3:
select film_id, titlefrom filmwhere film_id not in (1,2,3)between
The between operator allows you to check if a value falls within a range of values.
The basic syntax of the between operator is as follows:
value between low and high;If the value is greater than or equal to the low value and less than or equal to the high value, the between operator returns true; otherwise, it returns false.
You can rewrite the between operator by using the greater than or equal (>=) and less than or equal to ( <= ) operators and the logical and operator:
value >= low and value <= highIf you want to check if a value is outside a specific range, you can use the not between operator as follows:
value not between low and highThe following expression is equivalent to the expression that uses the not between operators:
value < low or value > highTasks
Find payments with payment_id is between 14503 and 14505:
select payment_id, amountfrom paymentwhere payment_id between 14503 and 14505Find payments with payment_id is not between 14503 and 14505:
select payment_id, amountfrom paymentwhere payment_id not between 14503 and 14505If you want to check a value against a date range, you use the literal date in ISO 8601 format, which is YYYY-MM-DD.
The following example uses the between operator to find payments whose payment dates are between 2007-02-15 and 2007-02-20 and amount more than 10:
select strftime('%Y-%m-%d', payment_date) as date, customer_id, payment_id, amountfrom paymentwhere strftime('%Y-%m-%d', payment_date) between '2005-02-15' and '2007-02-20' and amount > 10order by datelike
You can use the like operator to match the first names of customers with a string using the following query:
select first_name, last_namefrom customerwhere first_name like 'Jen%'The expression consists of the first_name, the like operator and a literal string that contains a percent sign (%). The string 'Jen%' is called a pattern.
The query returns rows whose values in the first_name column begin with Jen and are followed by any sequence of characters. This technique is called pattern matching.
You construct a pattern by combining literal values with wildcard characters and using the like or not like operator to find the matches.
SQLite offers two wildcards:
- Percent sign (
%) matches any sequence of zero or more characters. - Underscore sign (
_) matches any single character.
The like operator returns true if the value matches the pattern.
To negate the like operator, you use the not operator.
If the pattern does not contain any wildcard character, the like operator behaves like the equal (=) operator.
Tasks
Find customers whose first names contain the string er:
select first_name, last_namefrom customerwhere first_name like '%er%'order by first_nameFind customers whose first names starts with some letter followed by er:
select first_name, last_namefrom customerwhere first_name like '_er%'order by first_nameFind customers whose first names do not begin with Jen:
select first_name, last_namefrom customerwhere first_name not like 'Jen%'order by first_name`is null
To check if a value is null or not, you cannot use the equal to (=) or not equal to (<>) operators.
Instead, you use the is null operator.
The is null operator returns true if the value is null or false otherwise.
The is not null operator returns true if the value is not null or false otherwise.
SQLite offers some useful functions to handle null effectively such as nullif and coalesce.
Task: Sales People
We’ll use the following table that includes information on salespeople:
CREATE TABLE employees ( id INTEGER UNIQUE NOT NULL, first_name TEXT NOT NULL, last_name TEXT NOT NULL, salary INTEGER NOT NULL, commission_rate REAL NOT NULL, commission REAL, branch_id INTEGER NOT NULL);
INSERT INTO employees VALUES(11, 'Katarina', 'Rostova', 45000, 0.15, 47345.60, 1),(12, 'Alina', 'Park', 43000, 0.15, 45678.90, 2),(13, 'Meera', 'Malik', 50000, 0.15, 39045.63, 2),(17, 'Samar', 'Navabi', 52000, 0.14, 23023.45, 2),(18, 'Donald', 'Ressler', 40000, 0.14, 41345.75, 2),(20, 'Elisabeth', 'Keen', 59000, 0.14, 45350.00, 2),(21, 'Tom', 'Keen', 41000, 0.12, 41560.75, 1),(22, 'Dembe', 'Zuma', 40000, 0.12, 31540.70, 5),(23, 'Aram', 'Mojtabai', 50000, 0.12, 29050.65, 2),(30, 'Kate', 'Kaplan', 54000, 0.10, 25760.45, 5),(32, 'Marvin', 'Gerard', 55000, 0.10, 22500.00, 5),(34, 'Raymond', 'Reddington', 60000, 0.10, 17570.80, 5),(35, 'Harold', 'Cooper', 57000, 0.10, 15450.50, 2),(37, 'Ian', 'Garvey', 43000, 0.08, NULL, 1),(38, 'Ivan', 'Stepanov', 41000, 0.08, NULL, 1)Get the records of all employees whose annual salary is equal or greater than 50000, and order by salary:
select first_name, last_name, salary from employeeswhere salary >= 50000order by salary descList all employees who, thanks to their long experience with the company, have a commission rate above 0.12:
select first_name, last_name, commission_rate from employeeswhere commission_rate >= 0.12order by commission_rate descList the employees whose commission earnings were greater than their annual salary:
select first_name, last_name, salary, commission from employeeswhere commission > salaryList all employees whose commission rate is between 0.12 and 0.14:
select * from employeeswhere commission_rate between 0.12 and 0.14Retrieve information on all employees whose last name (when sorted alphabetically) is before ‘Keen’:
select first_name, last_name from employeeswhere last_name < 'Keen'order by last_nameList all employees whose last name starts with K:
select first_name, last_name from employeeswhere last_name like 'K%'order by last_nameRetrieve all records that have NULL in the commision column:
select first_name, last_name from employeeswhere commission is nullorder by last_nameRetrieve the records of ‘Kaplan’, ‘Gerard’ and ‘Zuma’:
select * from employeeswhere last_name in ('Kaplan', 'Gerard', 'Zuma')order by last_nameList all employees that work in branch 5 and have salaries equal to or greater than 5000:
select *from employeeswhere branch_id = 5 and salary >= 50000Get information on all employees except the ones who work in branch 2:
select *from employeeswhere not branch_id = 2Retrieve all records where their commission earnings were higher than their salary, and they are not working in branch #2
select *from employeeswhere commission > salary and not branch_id = 2Task: Population
Download population.csv
Retrieve countries of Asia that have a population greater than 100 million:
select "Country/Territory", "2022 Population" as Populationfrom populationwhere Continent = "Asia" and "2022 Population" > 100000000order by Population descRetrieve countries of Europe that have a population between 10 million and 15 million:
select *from populationwhere "Continent" = "Europe" and "2022 Population" between 10000000 and 15000000Get all countries that have less population in 2022 than in 1970:
select "Country/Territory", "2022 Population" - "1970 Population" as Difference, "Continent","2022 Population", "1970 Population"from populationwhere "1970 Population" > "2022 Population"order by Difference