SQL full mock exam
21 questions sampled across all 7 modules. Timed like the real thing: answer everything, then review the explanations.
What makes a column a primary key?
- It is the first column
- It uniquely identifies each row and is never null
- It is numeric
- It is indexed
Answer: It uniquely identifies each row and is never null — Uniqueness and not-null are the defining properties.
BETWEEN 100 AND 500 includes:
- 101 to 499
- 100 to 500
- 100 to 499
- 101 to 500
Answer: 100 to 500 — BETWEEN is inclusive on both endpoints.
SQL Server's equivalent of LIMIT 10 is:
- LIMIT 10
- TOP 10
- ROWNUM <= 10
- FIRST 10
Answer: TOP 10 — SQL Server uses TOP; Oracle uses FETCH FIRST or ROWNUM.
COUNT(*) is 500 and COUNT(email) is 480. Why?
- Duplicate rows
- 20 rows have a null email
- A join issue
- An index issue
Answer: 20 rows have a null email — COUNT on a column ignores nulls.
Which query is valid?
- SELECT region, city, SUM(t) FROM o GROUP BY region
- SELECT region, SUM(t) FROM o GROUP BY region
- SELECT region, city FROM o GROUP BY SUM(t)
- SELECT SUM(region) FROM o GROUP BY t
Answer: SELECT region, SUM(t) FROM o GROUP BY region — Every non-aggregated column must appear in GROUP BY.
Putting a row-level filter in HAVING instead of WHERE:
- Errors
- Usually works but is slower
- Is always faster
- Changes the result
Answer: Usually works but is slower — More rows reach the grouping step and are then thrown away.
Joining orders to line_items inflates SUM(total). Why?
- The join is wrong type
- Each order repeats once per line item
- Nulls are counted
- Missing index
Answer: Each order repeats once per line item — The one-to-many relationship duplicates the order row.
LEFT JOIN with WHERE right.status = 'x' behaves like:
- LEFT JOIN
- INNER JOIN
- CROSS JOIN
- FULL OUTER JOIN
Answer: INNER JOIN — The NULL-extended rows fail the WHERE and are discarded.
An INNER JOIN placed after a LEFT JOIN can:
- Speed up the query
- Eliminate the rows the LEFT JOIN preserved
- Change column order
- Have no effect
Answer: Eliminate the rows the LEFT JOIN preserved — The inner join requires a match, discarding null-extended rows.
Why does a join fail on values that look identical?
- Wrong data type
- Trailing whitespace or case differences
- Missing index
- Too many rows
Answer: Trailing whitespace or case differences — TRIM and case normalisation on import prevent both.
SELECT 7 / 2 in PostgreSQL returns:
- 3.5
- 3
- 4
- An error
Answer: 3 — Integer division discards the remainder. Cast to get 3.5.
Grouping monthly by a formatted string causes:
- An error
- Alphabetical sorting instead of chronological
- Duplicate rows
- Slower joins
Answer: Alphabetical sorting instead of chronological — April sorts before January as text. Truncate to a date instead.
A subquery referencing the outer query is:
- Scalar
- Correlated
- Derived
- Recursive
Answer: Correlated — Correlated subqueries are evaluated per outer row.
Derived tables in FROM usually require:
- An index
- An alias
- A GROUP BY
- A WHERE clause
Answer: An alias — Most dialects reject an unaliased derived table.
The main advantage of a CTE over nested subqueries is:
- Always faster
- Readable top-to-bottom structure and reuse
- Avoids indexes
- Allows aggregates
Answer: Readable top-to-bottom structure and reuse — Performance depends on whether the engine inlines it.
The main difference between a window function and GROUP BY:
- Speed
- Window functions retain every row
- Windows only work on numbers
- GROUP BY is deprecated
Answer: Window functions retain every row — That retention is the whole point.
With duplicate dates, RANGE differs from ROWS because:
- RANGE is faster
- RANGE includes all rows sharing the current ORDER BY value
- ROWS ignores nulls
- They are identical
Answer: RANGE includes all rows sharing the current ORDER BY value — That is why moving averages should specify ROWS.
LAG(revenue) on the first row returns:
- 0
- NULL unless a default is supplied
- The last row
- An error
Answer: NULL unless a default is supplied — The third argument supplies a default.
Which type should store a currency amount?
- FLOAT
- DECIMAL(10,2)
- REAL
- DOUBLE
Answer: DECIMAL(10,2) — DECIMAL is exact; floating point accumulates rounding error.
The difference between PRIMARY KEY and UNIQUE:
- None
- UNIQUE allows nulls, PRIMARY KEY does not
- PRIMARY KEY allows duplicates
- UNIQUE cannot be indexed
Answer: UNIQUE allows nulls, PRIMARY KEY does not — A table also has only one primary key.
DELETE differs from TRUNCATE because DELETE:
- Is faster
- Can be filtered with WHERE and rolled back
- Removes the table
- Resets identity columns
Answer: Can be filtered with WHERE and rolled back — TRUNCATE empties everything and usually cannot be rolled back.