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
Pattern Matching with LIKELIKE 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
ExamplesCombining 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
ExerciseWrite 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
Show hintsUseIN ('IT', 'HR')for the list andLIKE 'A%'for the pattern.A missing value is tested withIS NULL, never with= NULL.
Show solution
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
Quick quiz1. What does WHERE manager_id = NULL return?
A. The rows where manager_id is nullB. No rows, because a comparison with NULL is never trueC. All rowsD. A syntax error
Show answer
Show answerB. NULL means unknown, so the comparison is unknown too. Use IS NULL.
2. In a LIKE pattern, what does % match?
A. Exactly one characterB. A literal percent signC. Only digitsD. Any sequence of zero or more characters
Show answer
Show answerD. 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 tightlyB. As (a OR b) AND cC. Left to rightD. It is a syntax error
Show answer
Show answerA. Use parentheses whenever AND and OR are mixed, to make the intention explicit.
Interview questions
Interview questionsHow does NULL behave in comparisons?
Show answer
Show answerNULL 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
Show answerWHERE 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.
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