Course topics

By WebNest Studio Engineering Team

Database and SQL Tutorial

Filtering Data with WHERE

The WHERE clause filters which rows a SELECT, UPDATE, or DELETE statement affects, evaluating a boolean condition against each row and keeping only the rows where it evaluates to true. Precise filtering is one of the most frequently used SQL skills, and combining conditions correctly is essential to getting the right result set.

Why it matters

A table may hold millions of rows, and a query is useful only when it returns the right ones. The WHERE clause does that work. Its traps, especially how NULL behaves and how AND and OR combine, produce queries that run without error and quietly return the wrong rows.

Comparison Operators

Standard comparison operators — = != (or <>) > < >= <=</code> — compare a column against a value or another column. Comparing against NULL with = never returns true; NULL comparisons require the special IS NULL or IS NOT NULL operators instead.

Combining Conditions: AND, OR, IN, BETWEEN

Multiple conditions combine with AND (all must be true) and OR (at least one must be true); parentheses control precedence when mixing them. IN (value1, value2, ...) checks membership in a list, replacing a long chain of OR comparisons on the same column. BETWEEN low AND high checks an inclusive range, equivalent to column >= low AND column <= high</code>.

Pattern Matching with LIKE

LIKE performs simple pattern matching on text using two wildcards: % matches any sequence of characters (including none), and _ matches exactly one character. For example, name LIKE 'A%' matches any name starting with "A," and code LIKE 'A_1' matches a three-character code starting with "A" and ending with "1."

Examples

Combining AND, IN, and LIKE in one filtered query

SQL
SELECT name, department, salary
FROM employees
WHERE department IN ('Engineering', 'Sales')
  AND salary BETWEEN 50000 AND 90000
  AND name LIKE 'A%';
Output
Returns 1 row: ('Asha Rao', 'Engineering', 72000)

Filtering with OR and checking for NULL correctly

SQL
SELECT id, name, department
FROM employees
WHERE department = 'Sales' OR department IS NULL;
Output
Returns 2 rows: (2, 'Rohit Sharma', 'Sales'), (5, 'Meera Iyer', NULL)

Common Mistakes

  • Writing "column = NULL" instead of "column IS NULL" — equality comparisons with NULL always evaluate to unknown, never true.
  • Mixing AND and OR without parentheses, producing a condition that groups differently than intended (e.g., "WHERE dept = 'Sales' OR dept = 'HR' AND salary > 50000").
  • Using a leading wildcard in LIKE (e.g., "LIKE '%son'") and being surprised it cannot use a standard index efficiently on large tables.
  • Writing a long chain of "column = x OR column = y OR column = z" instead of the more readable and often faster "column IN (x, y, z)".

Exercise

Write two queries. First: the names of employees in the IT or HR department who earn more than 40000 and whose name starts with A. Second: the names of employees who have no manager.

Expected output: name, Asha, name, Zoya (one per line)

SQL · starter code
CREATE TABLE employees (id INTEGER PRIMARY KEY, name TEXT, department TEXT, salary INTEGER, manager_id INTEGER);
INSERT INTO employees (id, name, department, salary, manager_id) VALUES
  (1, 'Asha', 'IT', 50000, 3),
  (2, 'Amit', 'Sales', 60000, 3),
  (3, 'Zoya', 'HR', 70000, NULL),
  (4, 'Anil', 'IT', 35000, 1);

-- TODO: IT or HR, salary above 40000, name starting with A

-- TODO: employees with no manager
Show hints
  • Use IN ('IT', 'HR') for the list and LIKE 'A%' for the pattern.
  • A missing value is tested with IS NULL, never with = NULL.
Show solution
SQL · solution
CREATE TABLE employees (id INTEGER PRIMARY KEY, name TEXT, department TEXT, salary INTEGER, manager_id INTEGER);
INSERT INTO employees (id, name, department, salary, manager_id) VALUES
  (1, 'Asha', 'IT', 50000, 3),
  (2, 'Amit', 'Sales', 60000, 3),
  (3, 'Zoya', 'HR', 70000, NULL),
  (4, 'Anil', 'IT', 35000, 1);

SELECT name
FROM employees
WHERE department IN ('IT', 'HR')
  AND salary > 40000
  AND name LIKE 'A%';

SELECT name FROM employees WHERE manager_id IS NULL;

Quick quiz

1. What does WHERE manager_id = NULL return?

  • A. The rows where manager_id is null
  • B. No rows, because a comparison with NULL is never true
  • C. All rows
  • D. A syntax error
Show answer

B. NULL means unknown, so the comparison is unknown too. Use IS NULL.

2. In a LIKE pattern, what does % match?

  • A. Exactly one character
  • B. A literal percent sign
  • C. Only digits
  • D. Any sequence of zero or more characters
Show answer

D. The underscore, _, matches exactly one character.

3. How is a OR b AND c evaluated?

  • A. As a OR (b AND c), because AND binds more tightly
  • B. As (a OR b) AND c
  • C. Left to right
  • D. It is a syntax error
Show answer

A. Use parentheses whenever AND and OR are mixed, to make the intention explicit.

Interview questions

How does NULL behave in comparisons?

Show answer

NULL means the value is unknown, so any comparison with it, including = NULL and <> NULL, gives unknown and not true, and the row is filtered out. It is tested only with IS NULL and IS NOT NULL. A consequence is that WHERE status <> 'active' does not return rows whose status is null, and NOT IN with a list that contains a null returns no rows at all.

What is the difference between WHERE and HAVING?

Show answer

WHERE filters individual rows before any grouping takes place and cannot refer to aggregate functions. HAVING filters groups after GROUP BY has formed them and is where conditions on aggregates go, such as HAVING COUNT(*) > 5. Filtering in WHERE whenever possible is more efficient, because fewer rows reach the grouping step.

Key Points to Remember

  • WHERE filters rows using comparison operators, and NULL requires IS NULL / IS NOT NULL rather than = or !=.
  • AND requires all conditions to be true; OR requires at least one; parentheses control how they combine.
  • IN checks list membership and BETWEEN checks an inclusive range, both as shorthand for longer OR/comparison chains.
  • LIKE performs pattern matching using % (any sequence) and _ (single character) wildcards.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs your SQL on SQLite in your browser. Standard SQL works; a few features that exist only in PostgreSQL or MySQL do not. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

These examples need a project environment on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering