Filtering SELECT queries with the WHERE clause in MySQL.

Filtering SELECT query result sets is a common MySQL operation. This blog post will visit basic usage of the WHERE clause for just such a purpose.

Note: All data, names or naming found within the database presented in this post, are strictly used for practice, learning, instruction, and testing purposes. It by no means depicts actual data belonging to or being used by any party or organization.

I will be using Xubuntu Linux 16.04.2 LTS (Xenial Xerus) and MySQL 5.7.20 for these exercises.

About Where

The WHERE clause is used to filter results by specifying a filter condition or selection criteria.
Usage is not limited to just SELECT queries, as this clause is also used with the UPDATE and DELETE DML commands. However, we will concentrate on its usage for criteria filtering with SELECT queries in this blog post.


Syntax and Operators

The WHERE clause has the following syntax:
WHERE boolean_expression_conditional;
Selection criteria comparison is performed with any of one or more of the below operators:

  • <   : Less than.
  • >  : Greater than.
  • < = : Less than or equals to.
  • >= : Greater than or equals to.
  • = : Equals to.
  • != : Not equals to.
  • <> : Not equals to (alternate syntax).
  • IN() : Comparison function used for checking membership against a list of values or expressions.
  • NOT IN() : Comparison function used for checking membership not found in a list of values or expressions.

Multiple conditionals can be specified in the WHERE clause using either the AND or OR logical operators as in:

WHERE boolean_expression_one
AND
boolean_expression_two;

In the above scenario, both boolean expression conditionals must be true for a row (or rows) to make the final result set returned. (Note: This example shows only two filter conditions. More can be specified if desired.)

WHERE boolean_expression_one
OR
boolean_expression_two;

In this scenario, a row (or rows) is included in the final result set when either of the boolean expressions returns true.

Enough of the boring boilerplate yadda yadda. Let’s see some example uses of the WHERE clause.


Below is the description of the employees table from a mock HR database I will be using for many of these examples:

mysql> DESC employees;
+----------------+--------------+------+-----+---------+-------+
| Field          | Type         | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| EMPLOYEE_ID    | decimal(6,0) | NO   | PRI | 0       |       |
| FIRST_NAME     | varchar(20)  | YES  |     | NULL    |       |
| LAST_NAME      | varchar(25)  | NO   | MUL | NULL    |       |
| EMAIL          | varchar(25)  | NO   | UNI | NULL    |       |
| PHONE_NUMBER   | varchar(20)  | YES  |     | NULL    |       |
| HIRE_DATE      | date         | NO   |     | NULL    |       |
| JOB_ID         | varchar(10)  | NO   | MUL | NULL    |       |
| SALARY         | decimal(8,2) | YES  |     | NULL    |       |
| COMMISSION_PCT | decimal(2,2) | YES  |     | NULL    |       |
| MANAGER_ID     | decimal(6,0) | YES  | MUL | NULL    |       |
| DEPARTMENT_ID  | decimal(4,0) | YES  | MUL | NULL    |       |
+----------------+--------------+------+-----+---------+-------+
11 rows in set (0.05 sec)

Let’s have a look at all the available jobs in the employees table,

mysql> SELECT DISTINCT JOB_ID FROM employees;
+------------+
| JOB_ID     |
+------------+
| AC_ACCOUNT |
| AC_MGR     |
| AD_ASST    |
| AD_PRES    |
| AD_VP      |
| FI_ACCOUNT |
| FI_MGR     |
| HR_REP     |
| IT_PROG    |
| MK_MAN     |
| MK_REP     |
| PR_REP     |
| PU_CLERK   |
| PU_MAN     |
| SA_MAN     |
| SA_REP     |
| SH_CLERK   |
| ST_CLERK   |
| ST_MAN     |
+------------+

Single Conditionals

How about we retrieve the FIRST_NAME and LAST_NAMEof everyone who has the IT_PROG JOB_ID?

mysql> SELECT FIRST_NAME, LAST_NAME
    -> FROM employees
    -> WHERE JOB_ID = 'IT_PROG';
+------------+-----------+
| FIRST_NAME | LAST_NAME |
+------------+-----------+
| Alexander  | Hunold    |
| Bruce      | Ernst     |
| David      | Austin    |
| Valli      | Pataballa |
| Diana      | Lorentz   |
+------------+-----------+
5 rows in set (0.04 sec)

By specifying JOB_ID = 'IT_PROG'; in the WHERE clause, the above SELECT query is being filtered for only those records that have the JOB_ID column value of IT_PROG.


To receive notifications for the latest post from “Digital Owl’s Prose” via email, please subscribe by clicking the ‘Click To Subscribe!’ button in the sidebar!
Be sure and visit the “Best Of” page for a collection of my best blog posts.


Multiple Conditionals

More than one conditional can be provided to the WHERE clause.

Below the AND logical operator is used to specify two boolean expression conditionals in the WHERE clause.
Both conditionals must result to true, before any record(s) is included in the final result set.

mysql> SELECT FIRST_NAME, LAST_NAME, SALARY
    -> FROM employees
    -> WHERE JOB_ID = 'IT_PROG'
    -> AND SALARY < 5000;
+------------+-----------+---------+
| FIRST_NAME | LAST_NAME | SALARY  |
+------------+-----------+---------+
| David      | Austin    | 4800.00 |
| Valli      | Pataballa | 4800.00 |
| Diana      | Lorentz   | 4200.00 |
+------------+-----------+---------+
3 rows in set (0.00 sec)

The two conditionals checked in this WHERE clause are,

    • JOB_ID = 'IT_PROG'
    • SALARY < 5000
  • which is specifying that anyone working in the 'IT_PROG' job role, along with a SALARY less than 5000, is included in the returned results.

    OR is another logical operator often used. Using this operator, when either of the specified boolean expression conditionals returns as true, that record (or records) will be included in the final result set.

    mysql> SELECT FIRST_NAME, LAST_NAME, JOB_ID
        -> FROM employees
        -> WHERE JOB_ID = 'IT_PROG'
        -> OR
        -> JOB_ID = 'FI_ACCOUNT';
    +-------------+-----------+------------+
    | FIRST_NAME  | LAST_NAME | JOB_ID     |
    +-------------+-----------+------------+
    | Daniel      | Faviet    | FI_ACCOUNT |
    | John        | Chen      | FI_ACCOUNT |
    | Ismael      | Sciarra   | FI_ACCOUNT |
    | Jose Manuel | Urman     | FI_ACCOUNT |
    | Luis        | Popp      | FI_ACCOUNT |
    | Alexander   | Hunold    | IT_PROG    |
    | Bruce       | Ernst     | IT_PROG    |
    | David       | Austin    | IT_PROG    |
    | Valli       | Pataballa | IT_PROG    |
    | Diana       | Lorentz   | IT_PROG    |
    +-------------+-----------+------------+
    10 rows in set (0.00 sec)

    With this query, for a record to make the final result set, the JOB_ID can be either IT_PROG or FI_ACCOUNT.


    Checking For Membership

    The comparison functions IN() and NOT IN() check the specified value in the WHERE clause for membership found or not found, in a list of values or expressions.
    Let’s look at another example table in this database, the jobs table.

    mysql> DESC jobs;
    +------------+--------------+------+-----+---------+-------+
    | Field      | Type         | Null | Key | Default | Extra |
    +------------+--------------+------+-----+---------+-------+
    | JOB_ID     | varchar(10)  | NO   | PRI |         |       |
    | JOB_TITLE  | varchar(35)  | NO   |     | NULL    |       |
    | MIN_SALARY | decimal(6,0) | YES  |     | NULL    |       |
    | MAX_SALARY | decimal(6,0) | YES  |     | NULL    |       |
    +------------+--------------+------+-----+---------+-------+
    4 rows in set (0.00 sec)

    Suppose we know first hand we want to see the MAX_SALARY for certain job roles.
    Lets’ get an idea of the MAX_SALARY for the positions:Accountant, Stock Clerk, and Programmer.

    mysql> SELECT JOB_TITLE, MAX_SALARY
        -> FROM jobs
        -> WHERE JOB_TITLE IN ('Accountant','Stock Clerk','Programmer');
    +-------------+------------+
    | JOB_TITLE   | MAX_SALARY |
    +-------------+------------+
    | Accountant  |       9000 |
    | Stock Clerk |       5000 |
    | Programmer  |      10000 |
    +-------------+------------+
    3 rows in set (0.00 sec)

    Providing the list, ('Accountant','Stock Clerk','Programmer'), the JOB_TITLE column specified in the WHERE clause is checked against these values and returns that row, if any members of that list of values is present for that column.

    That same query can be run using multiple OR comparisons as well:

    mysql> SELECT JOB_TITLE, MAX_SALARY
        -> FROM jobs
        -> WHERE JOB_TITLE = 'Accountant'
        -> OR JOB_TITLE = 'Stock Clerk'
        -> OR JOB_TITLE = 'Programmer';
    +-------------+------------+
    | JOB_TITLE   | MAX_SALARY |
    +-------------+------------+
    | Accountant  |       9000 |
    | Stock Clerk |       5000 |
    | Programmer  |      10000 |
    +-------------+------------+
    3 rows in set (0.03 sec)

    Conversely, NOT IN() can be used to see what all the other positions besides 'Accountant', 'Stock Clerk', and 'Programmer' bring in for MAX_SALARY:

    mysql> SELECT JOB_TITLE, MAX_SALARY
        -> FROM jobs
        -> WHERE JOB_TITLE NOT IN ('Accountant','Stock Clerk','Programmer');
    +---------------------------------+------------+
    | JOB_TITLE                       | MAX_SALARY |
    +---------------------------------+------------+
    | President                       |      40000 |
    | Administration Vice President   |      30000 |
    | Administration Assistant        |       6000 |
    | Finance Manager                 |      16000 |
    | Accounting Manager              |      16000 |
    | Public Accountant               |       9000 |
    | Sales Manager                   |      20000 |
    | Sales Representative            |      12000 |
    | Purchasing Manager              |      15000 |
    | Purchasing Clerk                |       5500 |
    | Stock Manager                   |       8500 |
    | Shipping Clerk                  |       5500 |
    | Marketing Manager               |      15000 |
    | Marketing Representative        |       9000 |
    | Human Resources Representative  |       9000 |
    | Public Relations Representative |      10500 |
    +---------------------------------+------------+
    16 rows in set (0.04 sec)

    This query returns results for JOB_ID columns that are not an 'Accountant' ,'Stock Clerk' , or'Programmer'.


    Summarizing Where

    WHERE clauses are responsible for returning just what you want from a query result. Finding its usage in many of the DML commands: SELECTUPDATE, and DELETE, it is one of the most used clauses and in my opinion, one worth getting to know well.
    Explore the official MySQL 5.7 Online Manual for study, questions, and clarification.


    A Call To Action!

    Thank you for taking the time to read this post. I truly hope you discovered something interesting and enlightening. Please share your findings here, with someone else you know who would get the same value out of it as well.

    To receive notifications for the latest post from “Digital Owl’s Prose” via email, please subscribe by clicking the ‘Click To Subscribe!’ button in the sidebar!
    Be sure and visit the “Best Of” page for a collection of my best blog posts.


    Disclaimer: The examples presented in this post are hypothetical ideas of how to achieve similar types of results. They are not the utmost best solution(s). Your particular goals and needs may vary. Use those practices that best benefit your needs and goals. Opinions are my own.

Leave a Reply