Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →SQL interview answers often go wrong not because a candidate forgets a keyword, but because they misread what a query does to rows: a join multiplies matches, a filter runs at the wrong stage, ties are handled implicitly, or NULLs change a predicate’s meaning. There is no verified statistic showing what share of candidates fail these concepts. The useful takeaway is to practice explaining row counts, grouping, ordering, and missing values as you build a query.
What SQL topics are most commonly tested?
Two published question collections point to joins, aggregation, and window functions as recurring topics, but their figures describe different samples—not all employers or candidate failure rates.
| Source and date | Reported SQL question distribution | What the figures represent |
|---|---|---|
| DataDriven, updated July 27, 2026 | GROUP BY and aggregation: 24.5%; JOINs: 19.6%; window functions: 15.1%. The three categories total 60%. | Questions tracked on DataDriven’s platform; publisher-derived figures, not an independently sampled industry survey. DataDriven’s SQL interview guide |
| DataScienceHired, figures as of August 29, 2026 | In its bank of 100 SQL questions: joins 30; window functions 15; subqueries 12; GROUP BY 11. | A changing bank of published and tagged questions, cross-referenced with public interview reports and candidate write-ups. The report says its broader collection contains 389 questions tagged across 49 companies and 32 topics; company associations are not based on official company materials. DataScienceHired’s 2026 report |
The collections use different methods and categories, so their numbers should not be combined. Neither establishes what a particular employer will ask. They support prioritizing these concepts for practice, not claiming that “most candidates fail” them.
Why do joins produce unexpected row counts?
A join is a rule for matching rows, not simply a way to put two tables side by side. Before writing one, identify the intended grain of the output—one row per customer, order, or other entity—and determine whether the join key is unique on either side.
#1 Best Overall
Predict matches before choosing a join
An INNER JOIN returns rows for matching pairs. A LEFT JOIN preserves every left-side row and supplies NULLs for right-side columns when there is no match. If a key appears multiple times on both sides, each left-side occurrence can match each right-side occurrence, increasing the result beyond either table’s row count. PostgreSQL 18 documents these join behaviors in Joins Between Tables.
For example, if a customer has three order rows and two payment rows sharing the same customer ID, joining on that ID alone can produce six combinations for that customer. If the prompt needs one row per order, check whether the payment table needs to be aggregated or joined on a more specific key. Don’t assume a join preserves one row per entity.
- State which side’s unmatched rows, if any, the output must retain.
- Check key uniqueness and whether the relationship is one-to-one, one-to-many, or many-to-many.
- Predict the row count or output grain before and after each join; inspect duplicates if the result grows unexpectedly.
When should you use WHERE versus HAVING?
WHERE filters source rows before groups are formed. GROUP BY creates groups, and HAVING filters those groups using aggregate results. This distinction matters whenever the condition depends on a count, sum, or other aggregate.
Rank #2
Example: customers with more than two orders
SELECT customer_id, COUNT(*) AS order_count
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
HAVING COUNT(*) > 2;
Here, WHERE removes non-completed orders before the count is calculated; HAVING retains only customer groups whose completed-order count exceeds two. Moving the aggregate condition to WHERE would put it at the wrong stage.
Also distinguish COUNT(*), which counts rows, from COUNT(column), which counts non-NULL values in that column. If the counted column may be NULL, the two expressions can return different totals. PostgreSQL 18 explains grouping and aggregate behavior in its aggregate functions documentation.
How do window functions differ from GROUP BY?
A grouped aggregate usually produces one output row per group. A window function calculates across related rows while retaining the individual rows in the output, which makes it useful for rankings, running totals, and comparisons within a group.
Rank #3
Partition, order, and ties
PARTITION BY defines the groups over which a window calculation operates; ORDER BY defines its sequence or ranking. For top-N questions, decide how ties should behave:
ROW_NUMBER()assigns each row a distinct number. To select a repeatable “first” row, its ordering must fully resolve ties—for example, by adding a unique ID after the main sort key.RANK()gives tied values the same rank and leaves gaps after a tie.DENSE_RANK()gives tied values the same rank without gaps.
If a prompt asks for the top three scores, clarify whether it wants three rows at most or every row whose score falls within the top three ranks. Those are different results when scores tie. For running totals or moving calculations, inspect the window frame rather than relying on an unstated default. PostgreSQL 18 describes window usage in its window functions documentation.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesHow should you reason about NULLs and anti-joins?
NULL represents missing or unknown information, not an ordinary value. Test for it with IS NULL or IS NOT NULL, not = NULL. Comparisons involving NULL can evaluate to unknown, which affects which rows a filter returns.
Be cautious with NOT IN
If a NOT IN subquery can return NULL, the comparison may evaluate to unknown rather than true for values that otherwise appear absent. Consider NOT EXISTS or an anti-join pattern, but first decide how NULLs in the outer key and subquery should be treated. PostgreSQL documents these rules under comparison functions and operators.
Keep LEFT JOIN filters in the intended stage
A condition on the right table in the WHERE clause can remove rows where the right side is NULL, undoing the preservation intended by a LEFT JOIN. If the condition defines which right-side rows count as matches, putting it in ON can preserve unmatched left rows. If it belongs in WHERE, the resulting removal may be intentional. Check a small case with an unmatched left row to confirm. PostgreSQL’s table expressions documentation covers join conditions and filtering.
How can you make a multi-step SQL answer easier to explain?
For a prompt such as “find each customer’s first purchase and compare it with the prior month,” make the transformations explicit: identify relevant rows, calculate or rank the needed values, then produce the requested comparison. A common table expression (CTE) can give each stage a clear name.
Best Value
WITH ranked_purchases AS (
SELECT customer_id,
purchase_date,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY purchase_date, purchase_id
) AS purchase_number
FROM purchases
)
SELECT customer_id, purchase_date
FROM ranked_purchases
WHERE purchase_number = 1;
This example selects one earliest purchase per customer, using purchase_id to break same-date ties. If the prompt instead asks for all purchases tied on the earliest date, a ranking function that preserves ties would be more appropriate. CTEs clarify stages; they do not resolve ambiguous requirements or fix duplicate-key, NULL, or ordering problems. PostgreSQL 18 documents WITH queries in its CTE reference.
How should you practice SQL interview questions?
Write a query before looking at a solution, then narrate the intended grain of each intermediate result. Small test tables are especially useful when they include duplicated keys, unmatched rows, NULLs, and tied values—the cases most likely to expose assumptions.
- For each join, state the expected output grain and predict whether rows can multiply.
- For each filter, say whether it applies to source rows or grouped results.
- For each window function, identify its partition, ordering, and frame, then explain how ties are handled.
- Test missing values, empty or absent groups, date boundaries, and duplicate rows against the prompt.
- Check the target SQL engine before using syntax or behavior that may vary by dialect.
Review a solution for correctness against the prompt and table relationships, row preservation, duplicate handling, tie and NULL behavior, filter stage, clarity of intermediate steps, and dialect compatibility. These are useful self-review criteria, not a universal interviewer scoring rubric. PostgreSQL 18 is the dialect used in the examples above; other engines may differ in syntax and details.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




