SQL Practice Logo

SQLPractice Online

Comparison & Logical Operators: Mistakes

Module: SQL Fundamentals

Using = NULL instead of IS NULL

Wrong: WHERE deleted_at = NULL

Correct: WHERE deleted_at IS NULL

Always use IS NULL or IS NOT NULL for NULL comparisons.

= NULL always evaluates to UNKNOWN in three-valued logic, never TRUE — so the condition silently excludes all rows.

Mixing AND and OR without parentheses

Wrong: WHERE dept='Sales' OR dept='Mktg' AND salary > 80000

Correct: WHERE (dept='Sales' OR dept='Mktg') AND salary > 80000

Always add explicit parentheses when combining AND and OR.

AND has higher precedence than OR. `A OR B AND C` is parsed as `A OR (B AND C)`, not `(A OR B) AND C`.

NOT IN with a subquery that may return NULL

Dangerous: WHERE id NOT IN (SELECT nullable_col FROM ...)

Safe: WHERE NOT EXISTS (SELECT 1 FROM ... WHERE col = id)

Use NOT EXISTS instead of NOT IN when the subquery column is nullable.

If the subquery returns any NULL row, NOT IN evaluates every comparison as UNKNOWN, and zero rows are returned.

Leading wildcard LIKE causing full table scans

Slow: WHERE name LIKE '%phone'

Fast: WHERE name LIKE 'Samsung%'

Use trailing wildcards LIKE 'value%' or full-text search for substring matching.

LIKE '%value' cannot use a B-tree index — it must scan every row.

Using BETWEEN on DATETIME without accounting for end-of-day

Tricky: BETWEEN '2024-01-01' AND '2024-01-31'

Safe: >= '2024-01-01' AND < '2024-02-01'

Use explicit >= and < for date ranges on DATETIME columns.

BETWEEN '2024-01-01' AND '2024-01-31' misses rows with timestamp '2024-01-31 14:30:00' if the column is DATETIME.

OR on multiple indexed columns preventing index use

Slow: WHERE category_id = 5 OR status = 'active'

Fast: SELECT ... WHERE category_id = 5

UNION ALL

SELECT ... WHERE status = 'active' AND category_id != 5

Rewrite as UNION ALL to allow each branch to use its own index.

OR across different columns (WHERE a = 1 OR b = 2) often prevents the optimizer from using an index on either column.