For hiring managers, the pressure is familiar. Technical talent is hard to close, interview loops stretch, and good candidates disappear before the offer stage. For candidates, the pressure looks different. They need to prove they can do more than recite syntax from memory. They need to show judgment, data reasoning, and the ability to write queries that hold up in production.
That’s why strong SQL interviews shouldn’t stop at “write a query.” The best SQL query interview questions reveal how a person thinks when data is messy, requirements are incomplete, and business decisions depend on the output. A duplicate-records question tests data hygiene. A window-function question tests analytical depth. A multi-table join tests whether the candidate understands how systems relate, not just how tables connect.
This playbook is built for both sides of the table. Candidates can use it to practise the questions that come up repeatedly in data analyst, analytics engineering, business intelligence, and data engineering interviews. CHROs and hiring leaders can use the same questions as a structured hiring tool. The difference isn’t in the prompt. It’s in how you evaluate the answer.
Below are 10 practical SQL query interview questions with sample answers, recruiter signals, real-world scenarios, and the trade-offs that separate average performers from strong engineers.
Q) Write a Query to Find Duplicate Records in a Table
A candidate table with duplicate emails causes more damage than organizations expect. Recruiters call the same person twice, dashboards overstate pipeline volume, and conversion metrics become unreliable.
Say the table is candidates(candidate_id, full_name, email, updated_at). The interview prompt is simple: find emails that appear more than once.
SELECT
email,
COUNT(*) AS duplicate_count
FROM candidates
GROUP BY email
HAVING COUNT(*) > 1;What a strong answer looks like
That query is correct, but the interview value comes from the follow-up. Strong candidates ask whether NULL emails should count, whether email should be normalised to lower case, and whether whitespace should be trimmed.
A more production-aware version looks like this:
SELECT
LOWER(TRIM(email)) AS normalized_email,
COUNT(*) AS duplicate_count
FROM candidates
WHERE email IS NOT NULL
GROUP BY LOWER(TRIM(email))
HAVING COUNT(*) > 1;That response shows data quality thinking, not just SQL recall.
Practical rule: If a candidate solves duplicates without discussing normalisation, they’re answering the classroom version, not the hiring-system version.
Recruiter lens
Average candidates stop at GROUP BY and HAVING. Strong ones go further:
- Logic: They identify the right duplicate key.
- Code quality: They make the output readable with aliases.
- Business judgment: They explain why duplicate candidate records affect recruiter productivity and reporting integrity.
A useful live extension is: “Now return all duplicate rows, not just the duplicate email values.” That reveals whether the person can move from detection to investigation.
For teams refining interview readiness from the candidate side, even communication matters. The way someone explains query choices often mirrors how well they explain themselves in stakeholder settings. That’s why recruiter-facing coaching content such as self introduction tips for interviews from a recruiter aligns closely with technical interview performance too.
Q) Write a Query to Join Multiple Tables and Calculate Aggregate Functions
Most work happens here. Not in isolated tables, but across entities that need to be stitched together cleanly.
Suppose you have:
positions(position_id, title)applications(application_id, candidate_id, position_id, application_date)interviews(interview_id, application_id, interview_date)hires(hire_id, application_id, hire_date)
The prompt: find the number of interviewed candidates and average time to hire for each position.
SELECT
p.title,
COUNT(DISTINCT i.application_id) AS interviewed_candidates,
AVG(h.hire_date - a.application_date) AS avg_time_to_hire
FROM positions p
LEFT JOIN applications a
ON p.position_id = a.position_id
LEFT JOIN interviews i
ON a.application_id = i.application_id
LEFT JOIN hires h
ON a.application_id = h.application_id
GROUP BY p.title;Where candidates usually stumble
The common mistake is row multiplication. If one application has multiple interviews, the join can inflate counts and distort averages. Strong candidates catch that risk quickly.
They might pre-aggregate interviews or hires in separate CTEs before the final join. That’s a much better sign than someone who gets the query running but ignores duplication side effects.
A good interviewer follow-up is: “What happens if an application has three interviews?” If the candidate doesn’t spot the aggregation trap, they may struggle in analytics roles where metric definitions matter.
Recruiter lens
This question maps well to data-heavy hiring roles because it tests both coding and conceptual understanding.
- Coding skill: Can they write clean joins and valid aggregations?
- Conceptual skill: Can they explain grain, duplication risk, and metric integrity?
- Role alignment: Data analysts should discuss business definitions. Data engineers should also discuss indexing and execution behaviour.
For hiring managers building data teams, this question aligns closely with day-to-day work described in data analyst roles and responsibilities. Good answers connect query structure to reporting accuracy, stakeholder trust, and repeatable dashboards.
A candidate who says “I’d confirm the grain of each table before joining” is usually safer than one who writes a fast answer and moves on.
Q) Write a Query to Rank Records Using Window Functions
Ranking questions separate comfortable SQL users from candidates who can support real analytics workloads.
Use this scenario: rank candidates by interview score within each job category, highest first.
SELECT
candidate_id,
job_category,
interview_score,
DENSE_RANK() OVER (
PARTITION BY job_category
ORDER BY interview_score DESC
) AS score_rank
FROM candidate_scores;The true test isn’t syntax
The useful part comes after the first answer. Ask the candidate to explain ROW_NUMBER(), RANK(), and DENSE_RANK().
Strong candidates know:
ROW_NUMBER()gives each row a unique number, even with ties.RANK()leaves gaps after ties.DENSE_RANK()keeps rankings consecutive.
That distinction matters when a hiring team wants the “top 3 per category.” With ties, each function tells a different business story.
What works in senior interviews
For senior analytics or data engineering roles, add system thinking. Ask: “Would you compute ranking in the warehouse, in a BI tool, or in the application layer?”
A strong answer weighs freshness, consistency, and cost. If the same ranking logic appears in multiple reports, centralising it in SQL often improves consistency. If the ranking depends on interactive filters, the BI layer may be more flexible.
One industry shift is worth noting because it changes what advanced SQL interviews should cover. A DataCamp article states that, in India, data analytics roles surged by 45% in 2025 per Naukri.com’s job index, while cloud database adoption reached 62% of Indian enterprises per a NASSCOM cloud report for 2025.
That matters because a candidate who knows ranking in generic SQL but can’t reason about warehouse-scale execution may not be ready for modern production environments.
Q) Write a Query to Find Records NOT in Another Table
Anti-joins show whether a candidate understands missingness, which is where many funnel leaks hide.
Use a hiring example. Find all candidates who applied for a role but were never interviewed.
SELECT
a.candidate_id,
a.position_id
FROM applications a
LEFT JOIN interviews i
ON a.application_id = i.application_id
WHERE i.application_id IS NULL;Why this question matters
In recruitment analytics, missing records often reveal the most important process failures. Applications with no interview could signal screening backlog, weak recruiter follow-up, or role mismatch. The SQL is straightforward. The interpretation isn’t.
Candidates reach for NOT IN because it reads easily. The issue is that NOT IN can behave unexpectedly when nulls are involved. Strong candidates usually mention LEFT JOIN ... IS NULL or NOT EXISTS as safer patterns.
SELECT
a.candidate_id,
a.position_id
FROM applications a
WHERE NOT EXISTS (
SELECT 1
FROM interviews i
WHERE i.application_id = a.application_id
);How to assess strength
This question is effective for evaluating practical judgment because the answer has multiple valid forms.
Look for these signals:
- Average candidate: Writes a valid anti-join but can’t explain null behaviour.
- Strong candidate: Explains why
NOT EXISTSis often effective and discusses readability or optimiser behavior. - Senior candidate: Connects the result to funnel diagnosis and suggests how to operationalise the query in reporting.
A good live problem extension is to ask for “applied but not interviewed within seven days.” That combines anti-join logic with date filtering and introduces a service-level mindset.
Q) Write a Query to Calculate Running Totals or Cumulative Sums
Running totals are common in executive reporting, demand planning, and hiring progress tracking.
Scenario: calculate cumulative hires by month for the current year.
SELECT
hire_month,
hires_in_month,
SUM(hires_in_month) OVER (
ORDER BY hire_month
) AS cumulative_hires
FROM (
SELECT
DATE_TRUNC('month', hire_date) AS hire_month,
COUNT(*) AS hires_in_month
FROM hires
WHERE EXTRACT(YEAR FROM hire_date) = EXTRACT(YEAR FROM CURRENT_DATE)
GROUP BY DATE_TRUNC('month', hire_date)
) monthly_hires
ORDER BY hire_month;Why interviewers like this question
It combines grouping with window functions. Candidates have to know that the cumulative total should run over already-aggregated monthly results, not raw rows.
Weak answers try to do everything in one layer and get tangled. Strong answers simplify the problem first, then apply the window function.
Business interpretation matters
This question is especially useful for CHRO and talent analytics hiring because the output resembles the charts leadership teams review. A person who can produce the query but can’t explain what the curve means may still struggle in decision-support roles.
Ask one follow-up: “How would you compare cumulative actual hires against plan?” The stronger candidates suggest joining the monthly actuals to a targets table and calculating a variance column.
Field advice: Queries for reporting should be boring to read. If a running total answer is clever but hard to maintain, it won’t survive the next reporting cycle.
For senior roles, ask whether they’d materialise the monthly summary instead of recalculating on demand. That reveals thinking around scale, dashboard latency, and warehouse cost.
Q) Write a Query to Remove Duplicate Rows While Keeping One Record
Finding duplicates is one thing. Cleaning them safely is another.
Use this scenario: remove duplicate candidate records and keep the most recently updated row for each email.
WITH ranked_candidates AS (
SELECT
candidate_id,
email,
updated_at,
ROW_NUMBER() OVER (
PARTITION BY LOWER(TRIM(email))
ORDER BY updated_at DESC
) AS rn
FROM candidates
)
DELETE FROM candidates
WHERE candidate_id IN (
SELECT candidate_id
FROM ranked_candidates
WHERE rn > 1
);What separates a careful engineer
Good candidates do not rush to DELETE. They first show the same logic with a SELECT to verify which records would be removed.
WITH ranked_candidates AS (
SELECT
candidate_id,
email,
updated_at,
ROW_NUMBER() OVER (
PARTITION BY LOWER(TRIM(email))
ORDER BY updated_at DESC
) AS rn
FROM candidates
)
SELECT *
FROM ranked_candidates
WHERE rn > 1;That sequencing matters. In production systems, caution is part of technical quality.
Recruiter lens
This question is excellent for spotting habits, not just knowledge.
- Strong engineers mention transactions, backups, and validation.
- Average engineers focus only on getting a working delete statement.
- Risky hires ignore tie-breaking logic, such as what happens if two records share the same timestamp.
A useful variant for live interviews is to ask the candidate to “merge useful fields before deletion.” For example, keep the latest profile but preserve a phone number from the older record if the latest one is null. That turns a standard SQL task into a realistic data stewardship problem.
This is also where coding and conceptual skill split cleanly. The coding part is ROW_NUMBER(). The conceptual part is deciding what “keep one record” means in a business system.
Q) Write a Query to Find Records Between Two Dates
Date filtering looks basic. It isn’t. Many hiring dashboards break on date boundaries, time zones, or inclusive end dates.
Prompt: find all candidates who applied in Q3 2024.
SELECT
candidate_id,
position_id,
application_date
FROM applications
WHERE application_date >= DATE '2024-07-01'
AND application_date < DATE '2024-10-01';Why this is better than BETWEEN
Many candidates write:
WHERE application_date BETWEEN '2024-07-01' AND '2024-09-30'
That can work for pure date columns. It becomes risky when the field is a timestamp and includes time-of-day values. Using a half-open interval (>= start and < next_period_start) is usually safer and clearer.
This is one of the best beginner-to-intermediate sql query interview questions because it catches people who know syntax but haven’t worked through reporting edge cases.
What to listen for
A stronger candidate brings up three practical issues without prompting:
- Time stamps vs dates
- Time zone consistency
- Reusable period filters through views or parameterised logic
If you’re hiring for reporting-heavy roles, add a small business twist: “Return applications in Q3, grouped by week.” That checks whether the person can move from simple extraction to usable analysis.
A thoughtful answer also considers compliance and audit contexts. HR and recruitment reporting often depends on exact period definitions, and small date mistakes can create large downstream confusion in quarterly reviews.
Q) Write a Query Using CASE Statements for Conditional Logic
CASE statements reveal whether a candidate can translate business rules into SQL, which is a core skill in analytics and operations reporting.
Prompt: classify candidates as Senior, Mid-Level, or Junior based on years of experience.
SELECT
candidate_id,
full_name,
years_of_experience,
CASE
WHEN years_of_experience >= 8 THEN 'Senior'
WHEN years_of_experience >= 3 THEN 'Mid-Level'
ELSE 'Junior'
END AS candidate_level
FROM candidates;What makes this harder than it looks
Candidates treat CASE as a formatting tool. In practice, it’s a logic tool. The important part is not writing the syntax. It’s deciding whether the categories are mutually exclusive, complete, and aligned to the hiring team’s definition.
A good follow-up is: “What if some profiles have null experience?” Strong candidates handle that explicitly.
CASE
WHEN years_of_experience IS NULL THEN 'Unknown'
WHEN years_of_experience >= 8 THEN 'Senior'
WHEN years_of_experience >= 3 THEN 'Mid-Level'
ELSE 'Junior'
ENDLive problem example
Ask the candidate to score applications:
- shortlisted and interview score above threshold
- shortlisted but score pending
- rejected
- in review
This tests prioritisation logic and order of conditions. CASE executes top to bottom. A person who understands that will usually write safer classification rules.
“The best CASE statements read like policy. If I can’t map each branch to a business rule, I rewrite it.”
Recruiter lens
This question is useful when hiring analysts who work closely with recruiters, finance teams, or business leaders. It shows whether they can convert ambiguous verbal rules into repeatable query logic without losing edge cases.
Average candidates write a working CASE. Stronger candidates ask who owns the definitions and whether those definitions should live in SQL, a lookup table, or application logic.
Q) Write a Query to Calculate Year over Year Hiring Metrics Comparison
Year over year analysis is where SQL interviews start to resemble strategic workforce planning.
Prompt: compare total hires by month for the current year against the previous year.
WITH monthly_hires AS (
SELECT
EXTRACT(YEAR FROM hire_date) AS hire_year,
EXTRACT(MONTH FROM hire_date) AS hire_month,
COUNT(*) AS total_hires
FROM hires
GROUP BY
EXTRACT(YEAR FROM hire_date),
EXTRACT(MONTH FROM hire_date)
)
SELECT
curr.hire_month,
curr.total_hires AS current_year_hires,
prev.total_hires AS previous_year_hires
FROM monthly_hires curr
LEFT JOIN monthly_hires prev
ON curr.hire_month = prev.hire_month
AND curr.hire_year = prev.hire_year + 1
WHERE curr.hire_year = EXTRACT(YEAR FROM CURRENT_DATE)
ORDER BY curr.hire_month;What stronger candidates add
They don’t stop at counts. They ask whether the comparison should control for seasonality, hiring freezes, or role mix. That’s exactly the kind of analytical maturity hiring leaders want in planning roles.
If the interviewer asks for average time to hire year over year too, better candidates usually avoid stuffing all logic into one giant query. They build separate monthly aggregates and join them cleanly.
Why this matters for CHROs
YoY metrics are often used to defend budget, explain recruiting capacity, and assess whether process changes are helping. The query is technical. The use case is executive.
For a broader strategic context on how teams operationalise this kind of measurement, talent analytics meaning, types, process, challenges provides a useful lens on how reporting moves from data extraction to decision support.
Evaluation signals
- Logic: Are months aligned correctly across years?
- Scalability thinking: Would they pre-aggregate large event tables?
- Code quality: Is the query modular enough for a teammate to extend?
This is also a good place to test communication. Ask the candidate to explain the result as if speaking to a CHRO, not a DBA.
Q) Write a Query Using Subqueries or CTEs to Solve Complex Problems
This final question reveals if the candidate can structure thought, not just write fragments.
Prompt: find the top 3 highest-scoring candidates for each job position who are currently available.
Assume:
applications(candidate_id, position_id)candidate_scores(candidate_id, score)candidate_status(candidate_id, employment_status)
WITH available_candidates AS (
SELECT
candidate_id
FROM candidate_status
WHERE employment_status = 'Available'
),
scored_candidates AS (
SELECT
a.position_id,
a.candidate_id,
s.score
FROM applications a
JOIN candidate_scores s
ON a.candidate_id = s.candidate_id
JOIN available_candidates ac
ON a.candidate_id = ac.candidate_id
),
ranked_candidates AS (
SELECT
position_id,
candidate_id,
score,
ROW_NUMBER() OVER (
PARTITION BY position_id
ORDER BY score DESC
) AS rn
FROM scored_candidates
)
SELECT
position_id,
candidate_id,
score
FROM ranked_candidates
WHERE rn <= 3;Why this question works so well
It forces decomposition. Candidates need to decide what belongs in each step, how to keep naming clear, and where ranking should happen.
Subqueries can solve the same problem, but CTEs usually make the reasoning easier to follow. That’s why this question is such a good proxy for maintainability in real codebases.
System design thinking for senior roles
Push one step further: “How would this work if candidate availability updates constantly and recruiters need near-real-time shortlists?”
Now the conversation moves beyond SQL syntax into architecture:
- materialised views or scheduled refreshes
- warehouse versus application-serving layer
- freshness versus cost
- ownership of business logic
That is exactly the bridge between technical interviewing and strategic hiring.
Hiring signal: Senior candidates explain not only how to write the query, but where it should live, how it should be tested, and who should trust its output.
Comparison of 10 SQL Interview Queries
| Query | Complexity | Resources / Performance | Expected outcomes | Ideal use cases | Key advantages |
|---|---|---|---|---|---|
| Write a Query to Find Duplicate Records in a Table | Low (basic GROUP BY/HAVING) | Low-Moderate; scales with indexes | Exact duplicate counts per key | Data quality checks, dedup audits | Simple, fast detection of duplicates |
| Write a Query to Join Multiple Tables and Calculate Aggregate Functions | Medium (multiple JOINs + GROUP BY) | Moderate-High; sensitive to indexing | Combined KPIs across entities (counts, averages) | Hiring dashboards, KPI reporting | Broad cross-table analytics |
| Write a Query to Rank Records Using Window Functions | Medium (requires window syntax) | Moderate; efficient vs self-joins, DB must support windows | Ordered rankings within partitions | Shortlisting, candidate prioritization | Elegant ranking, handles ties well |
| Write a Query to Find Records NOT in Another Table (Anti-Join) | Low-Medium (LEFT JOIN/NOT EXISTS) | Low-Moderate; efficient with FK/indexes | Identifies missing relationships/gaps | Process audits, identify stalled candidates | Pinpoints funnel leaks and compliance gaps |
| Write a Query to Calculate Running Totals or Cumulative Sums | Medium (window SUM() OVER()) | Moderate; depends on partitioning and ordering | Cumulative trends and running metrics | Forecasting, cumulative hiring dashboards | Clear trend visibility for planning |
| Write a Query to Remove Duplicate Rows While Keeping One Record (Deduplication) | Medium-High (CTEs + DELETE) | High; destructive, needs backups & testing | Cleaned dataset retaining desired record | Database maintenance, periodic cleanup | Preserves most recent/accurate records |
| Write a Query to Find Records Between Two Dates (Date Range Filtering) | Low (simple WHERE BETWEEN) | Low; very efficient when dates indexed | Time-bound record sets (quarterly, YTD) | Quarterly reports, compliance windows | Readable, easy to parameterize |
| Write a Query Using CASE Statements for Conditional Logic | Medium (conditional logic in SELECT) | Low-Moderate; minimal resource overhead | Categorized or scored records | Candidate segmentation, scoring rules | Flexible implementation of business rules |
| Write a Query to Calculate Year-over-Year (YoY) Hiring Metrics Comparison | High (date math + grouping) | Moderate-High; handle partial years and joins | Comparative trends across years | Executive reporting, budget justification | Demonstrates program impact and trends |
| Write a Query Using Subqueries or CTEs to Solve Complex Problems | High (multi-step logic and composition) | Moderate-High; readable but may be heavy | Modular, staged analytical results | Complex shortlists, multi-criteria analytics | Maintainable, reusable query components |
From Query to Hire Your Strategic RPO Partnership
A common mistake in SQL interviews is treating them like syntax exams. That approach rarely helps hiring teams identify who can perform once the role gets messy. Production data is messy. Stakeholder questions are messy. Hiring operations are messy. A candidate who can only solve neat textbook prompts won’t hold up for long in a live environment.
The stronger engineers do three things consistently. First, they explain their logic clearly. Second, they surface trade-offs without being prompted. Third, they connect technical decisions to business outcomes. When someone says, “This join could duplicate rows unless we pre-aggregate interviews,” that’s not just SQL fluency. That’s analytical discipline. When someone says, “I’d use a half-open date range because timestamps can break month-end reporting,” that’s operational awareness. Those are the signals worth hiring for.
A practical evaluation rubric keeps interviews more consistent across panels. Use three lenses.
- Logic: Is the answer correct, complete, and handles edge cases effectively?
- Scalability thinking: Will the approach still make sense on large datasets, warehouse systems, and recurring dashboards?
- Code quality: Is the SQL readable, modular, and maintainable by another analyst or engineer?
That rubric also helps separate coding ability from conceptual ability. Some candidates can produce a working query but struggle to explain why the result can be trusted. Others may not recall syntax instantly but reason well, ask sharp clarifying questions, and improve quickly. In many hiring situations, the second profile is stronger.
For Indian enterprises hiring data talent, the problem usually isn’t just identifying SQL skill. It’s doing it fast enough, fairly enough, and consistently enough across multiple business units. Teams face talent shortages in specialist roles, long hiring cycles, and avoidable drop-offs when interviews feel repetitive or poorly structured. SQL rounds often contribute to that problem because they’re generic, inconsistent, or disconnected from the actual role.
The top five hiring mistakes in tech roles show up repeatedly:
- Over-relying on generic tests that don’t reflect the actual data environment.
- Running interviews without a framework for analytical thinking.
- Stretching the process so long that strong candidates disengage.
- Failing to explain the business impact of the role to in-demand talent.
- Depending on broad sourcing rather than role-specific talent pipelines.
A better model treats SQL assessment as part of a hiring system. Start with role calibration. A data analyst may need strong joins, aggregation, and business logic through CASE statements. A data engineer may need deeper skill in window functions, large-table reasoning, and warehouse-aware optimisation. A senior analytics leader may need all of that plus the ability to design reusable metrics and explain trade-offs to non-technical stakeholders.
A downloadable interview rubric helps standardise that process. Include the prompt, expected solution patterns, common mistakes, extension questions, and a scorecard for logic, scalability, and code quality. Add room for interviewer notes on communication, business reasoning, and stakeholder readiness. That turns a technical interview into a repeatable hiring asset.
Scaling tech hiring requires specialized sourcing + assessment frameworks. That’s where an RPO partner becomes more than a recruitment vendor. Taggd combines hiring expertise, data-led assessment design, and enterprise-scale recruiting operations to help teams evaluate talent with more rigour and move faster without lowering the bar. If your team is hiring SQL-heavy roles across analytics, engineering, or digital transformation functions, the right partner can shorten the path from shortlist to successful hire.
Taggd helps enterprise hiring teams in India turn technical interviews into structured hiring systems. If you’re scaling data, analytics, or engineering recruitment, Taggd can support specialised sourcing, sharper assessment design, and faster execution across the full hiring lifecycle.