Interview Problems: Easy

The easy SQL problems that open most interviews: second-highest value, duplicates, rows with no match, day-over-day change, self-joins and top-by-count, each with a runnable answer.

Overview

Easy SQL problems are the warm-up in phone screens and the first minutes of a data or backend interview. The logic is short. What the interviewer watches is whether you pick the right pattern at once, write clean SQL without trial and error, and think about the edge cases on your own: NULLs, ties, gaps and empty results.

Almost every easy problem is one of a handful of patterns.

  • the Nth highest value — MAX below the max, OFFSET, or DENSE_RANK
  • values that repeat — GROUP BY ... HAVING COUNT(*) > 1
  • rows with no match in another table — NOT EXISTS or LEFT JOIN ... IS NULL
  • comparing a row with the previous day or row — self-join on the date, or LAG
  • comparing a row with a related row in the same table — self-join
  • the entity with the most of something — GROUP BY, ORDER BY COUNT(*) DESC
  • a rate or share — AVG(CASE WHEN ... THEN 1 ELSE 0 END)

The problems below are written in our own words. Each one creates its own tiny tables, so you can run every block in order in PostgreSQL.

Second-highest distinct salary

Given a table of staff with salaries, return the second-highest distinct salary. If there is no such salary, return a single row holding NULL.

  • 9000

An aggregate with no input rows returns NULL, so this answer already handles a table with one salary. For the Nth highest, use DISTINCT with OFFSET, and wrap it in a scalar subquery: a query that finds nothing returns zero rows, but a scalar subquery that finds nothing returns NULL.

  • 9000
  • Two people share the top salary — OFFSET 1 without DISTINCT returns the top salary again — DISTINCT or DENSE_RANK
  • Only one distinct salary — the query returns no row — MAX or a scalar subquery returns NULL

Emails that appear more than once

Given a table of sign-ups, list every email address that was used for more than one sign-up.

  • a@x.com
  • b@x.com

WHERE filters rows before grouping; HAVING filters groups after it. A count belongs in HAVING. The follow-up is often to delete the extra copies: see the DELETE ... USING pattern in the DDL & DML topic.

Customers who never bought anything

Given shoppers and purchases, return the shoppers with no purchase at all.

  • Ben

LEFT JOIN purchases p ON p.shopper_id = s.id WHERE p.id IS NULL gives the same answer. Test a column that cannot be NULL in a matched row, such as the right table's primary key. The version to avoid is NOT IN: purchase 13 has a NULL shopper, and one NULL in the subquery makes NOT IN unknown for every shopper.

  • (no rows)
  • NOT EXISTS — yes
  • LEFT JOIN ... IS NULL on the right key — yes
  • NOT IN (subquery) — no: returns nothing

Days warmer than the day before

Given one temperature reading per date, return every date that was warmer than the calendar day before it. A date whose previous day has no reading does not count.

  • 2026-03-02
  • 2026-03-06

In PostgreSQL, a date minus an integer is a date. MySQL uses DATE_SUB(day, INTERVAL 1 DAY) or DATEDIFF, and SQL Server uses DATEADD.

The trap is LAG(temp) OVER (ORDER BY day). LAG compares with the previous row, not the previous day, so it also returns 2026-03-05, whose previous row is March 3. If you use LAG, also check that LAG(day) equals day - 1.

Staff paid more than their manager

Each staff row names its manager's id. Return the staff who earn more than their own manager.

  • Lena

The inner join drops Ava, who has no manager. That is right here; use a LEFT JOIN when the question asks to keep rows without a match.

The customer with the most orders

Return the shopper who placed the most purchases. The problem promises exactly one winner.

  • 1

Say the follow-up before the interviewer does: with ties, LIMIT 1 returns an unpredictable one of the tied winners. To return every tied winner, rank the counts with RANK() OVER (ORDER BY COUNT(*) DESC) and keep rank 1.

The largest number that appears once

Given a column of numbers that may repeat, return the largest number that appears exactly once, or NULL if every number repeats.

  • 6

The outer MAX turns an empty set of singles into NULL, which is what the problem asks for.

What you will be able to do

  • Recognize the pattern behind an easy SQL problem within a minute.
  • Return NULL, not an empty result, when a problem asks for it.
  • Explain why NOT IN fails with NULLs and what to use instead.
  • Handle ties and date gaps before the interviewer asks.

When to use it

  • Phone screens and warm-up rounds, where speed and accuracy count
  • Problems that need one filter, one grouping or one join
  • Finding duplicates, missing matches or the Nth-highest value
  • Comparing a row with the previous day, or with a related row in the same table
  • Practicing pattern recognition so easy problems take a few minutes

Sign up free to read the full topic

More Databases & SQL topics

Start free on Cariara · Coding problems · System design studio