Lab 04: Filtering and Sorting

Time: 30 minutes | Level: Foundations | DB: MySQL 8 / PostgreSQL 15

Overview

Master the WHERE clause with comparison operators, logical operators, pattern matching, ORDER BY, LIMIT/OFFSET, and pagination patterns.


Step 1: Setup — Sample Dataset

docker run -d --name mysql-lab -e MYSQL_ROOT_PASSWORD=rootpass mysql:8.0
for i in $(seq 1 30); do docker exec mysql-lab mysql -uroot -prootpass -e "SELECT 1" 2>/dev/null && break || sleep 2; done

docker exec mysql-lab mysql -uroot -prootpass << 'EOF'
CREATE DATABASE store;
USE store;

CREATE TABLE employees (
    emp_id      INT NOT NULL AUTO_INCREMENT,
    first_name  VARCHAR(50) NOT NULL,
    last_name   VARCHAR(50) NOT NULL,
    department  VARCHAR(50) NOT NULL,
    salary      DECIMAL(10,2) NOT NULL,
    hire_date   DATE NOT NULL,
    is_active   BOOLEAN DEFAULT TRUE,
    email       VARCHAR(100),
    PRIMARY KEY (emp_id)
);

INSERT INTO employees (first_name, last_name, department, salary, hire_date, email) VALUES
('Alice',   'Johnson',  'Engineering',  95000, '2020-03-15', '[email protected]'),
('Bob',     'Smith',    'Marketing',    72000, '2019-07-22', '[email protected]'),
('Carol',   'Davis',    'Engineering',  110000,'2018-01-10', '[email protected]'),
('David',   'Wilson',   'HR',           65000, '2021-09-01', '[email protected]'),
('Eve',     'Martinez', 'Engineering',  98000, '2020-11-30', '[email protected]'),
('Frank',   'Anderson', 'Marketing',    68000, '2022-02-14', NULL),
('Grace',   'Taylor',   'HR',           70000, '2019-05-20', '[email protected]'),
('Henry',   'Thomas',   'Engineering',  125000,'2017-08-05', '[email protected]'),
('Isabel',  'Jackson',  'Finance',      88000, '2021-12-01', '[email protected]'),
('Jack',    'White',    'Finance',      92000, '2020-06-18', '[email protected]'),
('Karen',   'Harris',   'Marketing',    75000, '2018-10-25', '[email protected]'),
('Liam',    'Clark',    'Engineering',  105000,'2019-03-08', '[email protected]');
EOF

Step 2: Comparison Operators

📸 Verified Output (salary > 100000):


Step 3: BETWEEN, IN, NOT IN

📸 Verified Output (BETWEEN):

💡 BETWEEN a AND b is equivalent to >= a AND <= b. It's inclusive on both ends.


Step 4: LIKE and ILIKE Pattern Matching

📸 Verified Output (last_name LIKE 'J%'):

PostgreSQL ILIKE (case-insensitive LIKE):

💡 In MySQL, LIKE case sensitivity depends on column collation. In PostgreSQL, LIKE is always case-sensitive; use ILIKE for case-insensitive matching.


Step 5: AND, OR, NOT

📸 Verified Output (AND: Engineering AND salary > 100000):

⚠️ Without parentheses, AND has higher precedence than OR. Always use parentheses when mixing AND and OR.


Step 6: ORDER BY

📸 Verified Output (ORDER BY department ASC, salary DESC):


Step 7: LIMIT and OFFSET

📸 Verified Output (LIMIT 5, top earners):


Step 8: Capstone — Pagination Pattern

Build a reusable pagination query. Assume page size = 3, getting page 2:

📸 Verified Output:

The pagination formula:

💡 For large datasets, OFFSET-based pagination gets slow (DB must scan and skip). For tables with millions of rows, use keyset/cursor pagination: WHERE id > last_seen_id LIMIT n.

Cleanup:


Summary

Feature
MySQL
PostgreSQL
Notes

Equals

=

=

Not equals

!= or <>

!= or <>

Range

BETWEEN a AND b

Same

Inclusive

List match

IN (a, b, c)

Same

Pattern

LIKE '%x%'

LIKE '%x%'

MySQL case-insensitive by collation

Case-insensitive pattern

N/A (by collation)

ILIKE '%x%'

PG-specific

Sort ascending

ORDER BY col ASC

Same

ASC is default

Sort descending

ORDER BY col DESC

Same

Limit rows

LIMIT n

LIMIT n

Skip rows

LIMIT n OFFSET m

LIMIT n OFFSET m

Next: Lab 05 — Aggregate Functions

Last updated