-
SQL
- Write a SQL query to find the second highest salary from an Employees table without using LIMIT or TOP.
- Write a query to find all customers who placed orders in every month of 2025.
- Write a query to identify duplicate rows in a Transactions table based on customer_id, amount, and date.
- Write a query using GROUP BY and HAVING to find departments with more than 10 employees earning above the department average salary.
- Write a query to return the top 3 selling products per category using a subquery (no window functions allowed).
- Write a query to calculate the running total of daily revenue for a store using a self-join.
- Write a query to find the average order value per customer segment, excluding cancelled orders.
- Write a query to find employees who earn more than their direct manager, using a self-join on an Employees table.
- Write a query to list all customers who have not placed any order in the last 90 days.
- Write a query to compute the percentage of total revenue contributed by each product category.
- Write a query to find the first purchase date and last purchase date for every customer.
- Write a query to find the three most recent orders for each customer.
- Write a query that returns customers whose total spend is above the 90th percentile of all customers.
- Write a query to find customers who bought Product A but never bought Product B.
- Write a query to count how many orders each customer placed and rank customers by order count within their city.
- Write a query to identify the busiest hour of the day for support ticket creation using a Tickets table.
- Write a query to find the top 5 referral sources by conversion rate from a Signups table.
- Write a query using EXISTS to find suppliers who have never had a late delivery.
- Write a query to detect gaps in a sequential invoice_number column.
- Write a query to find all products whose price increased in the last price update compared to the previous one.
- Write a query to calculate month-over-month growth rate in active users from a DailyActiveUsers table.
- Write a query to return the department with the highest average tenure of employees.
- Write a query to find all orders placed on weekends versus weekdays and compare average order value.
- Write a query to find customers who upgraded their subscription plan more than once in the last year.
- Write a query to return the top 10% of sales reps by revenue generated in Q1.
- Write a query using a CTE to calculate a 7-day moving average of website visits.
- Write a query to find all patients who missed at least two scheduled appointments in the past year.
- Write a query to identify employees who have never taken a single day of leave in the last two years.
- Write a query to compute year-over-year revenue comparison for each region using self-joins.
- Write a query to find the longest streak of consecutive days a user logged into an app.
- Write a query to identify vendors whose invoice amounts differ by more than 15% from their historical average.
- Write a query to find all students who scored above the class average in more than 3 subjects.
- Write a query to detect accounts with more than 5 failed login attempts within a 10-minute window.
- Write a query to find the second most frequently ordered item for each customer.
- Write a query to identify products frequently bought together, based on an OrderItems table.
- Write a query to find the average time between a support ticket being opened and first responded to, grouped by priority.
- Write a query to find the top-selling product in each store location for the current quarter.
- Write a query to list all foreign keys referencing a given table in a schema (engine-specific system tables allowed).
- Write a query to compute the cumulative distinct count of new customers acquired each month.
Answer
Use conditional aggregation - a SUM(CASE WHEN month = X THEN value END) per month - to turn 12 rows into 12 columns.
Solution
SELECT
SUM(CASE WHEN MONTH(sale_date) = 1 THEN amount END) AS Jan,
SUM(CASE WHEN MONTH(sale_date) = 2 THEN amount END) AS Feb,
SUM(CASE WHEN MONTH(sale_date) = 3 THEN amount END) AS Mar,
SUM(CASE WHEN MONTH(sale_date) = 4 THEN amount END) AS Apr,
SUM(CASE WHEN MONTH(sale_date) = 5 THEN amount END) AS May,
SUM(CASE WHEN MONTH(sale_date) = 6 THEN amount END) AS Jun,
SUM(CASE WHEN MONTH(sale_date) = 7 THEN amount END) AS Jul,
SUM(CASE WHEN MONTH(sale_date) = 8 THEN amount END) AS Aug,
SUM(CASE WHEN MONTH(sale_date) = 9 THEN amount END) AS Sep,
SUM(CASE WHEN MONTH(sale_date) = 10 THEN amount END) AS Oct,
SUM(CASE WHEN MONTH(sale_date) = 11 THEN amount END) AS Nov,
SUM(CASE WHEN MONTH(sale_date) = 12 THEN amount END) AS Dec
FROM Sales;Step by Step
- Each
CASE WHEN MONTH(sale_date) = N THEN amount ENDreturns the sale amount only for rows in month N, andNULLfor every other row. - Wrapping each in
SUM()adds up just that month's non-null values - effectively a mini filtered total per column. - Twelve of these side by side turn 12 rows of monthly data into a single wide row with one column per month.
Alternative Method: Native PIVOT (SQL Server / Some Engines)
SELECT * FROM (
SELECT MONTH(sale_date) AS mth, amount FROM Sales
) src
PIVOT (
SUM(amount) FOR mth IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) piv;Engines with a native PIVOT operator (like SQL Server) can express this more compactly, though the underlying logic - grouping and conditionally summing per category - is identical to the CASE approach, which works on virtually every SQL engine.
Key Exam Traps
- Missing END defaults to NULL, not 0 - which is exactly what makes
SUM()correctly ignore non-matching rows. Adding an explicitELSE 0would still work sinceSUM()treats 0 as 0, but it's unnecessary. - Multiple years of data: This query silently merges all years together into one "Jan" total if the data spans more than one year - a
WHERE YEAR(sale_date) = 2025filter is usually needed alongside it for a single year's pivot. - Column-per-value pivoting requires knowing the values in advance - this only works cleanly because there are exactly 12 known months; pivoting on an unknown or growing set of categories requires dynamic SQL instead.