50 SQL Interivew Queries PDF
50 SQL Interivew Queries PDF
SELECT MAX(salary) AS
SecondHighestSalary
FROM Employee
WHERE salary < (SELECT MAX(salary)
FROM Employee);
3. Find employees without
department (Left Join usage)
SELECT e.*
FROM Employee e
LEFT JOIN Department d
ON e.department_id =
d.department_id
WHERE d.department_id IS NULL;
4. Calculate the total revenue per
product
SELECT product_id,
SUM(quantity * price) AS
total_revenue
FROM Sales
GROUP BY product_id;
5. Get the top 3 highest-paid
employees.
SELECT TOP 3 *
FROM Employee
ORDER BY salary DESC;
6. Customers who made purchases
but never returned products.
SELECT customer_id,
COUNT(*) AS order_count
FROM Orders
GROUP BY customer_id;
8. Retrieve all employees who joined
in 2023.
SELECT *
FROM Employee
WHERE YEAR(hire_date) = 2023;
9. Calculate the average order value
per customer.
SELECT customer_id,
AVG(total_amount) AS
avg_order_value FROM
Orders GROUP BY
customer_id;
10. Get the latest order placed by
each customer.
SELECT customer_id,
MAX(order_date) AS
latest_order_date
FROM Orders
GROUP BY customer_id;
11. Find products that were never
sold.
SELECT p.product_id
FROM Products p
LEFT JOIN Sales s
ON p.product_id = s.product_id
WHERE s.product_id IS NULL;
12. Identify the most selling product.
SELECT region,
SUM(total_amount) AS total_revenue,
COUNT(*) AS order_count
FROM Orders
GROUP BY region;
14. Count how many customers
placed more than 5 orders.
SELECT *
FROM Orders
WHERE total_amount >
(SELECT AVG(total_amount)
FROM Orders);
16. Find all employees hired on
weekends.
SELECT *
FROM Employee
WHERE DATENAME(WEEKDAY, hire_date)
IN ('Saturday', 'Sunday');
17. Find all employees hired on
weekends.
SELECT *
FROM Employee
WHERE salary BETWEEN 50000 AND
100000;
18. Get monthly sales revenue and
order count.
SELECT
FORMAT(date, 'yyyy-MM') AS month,
SUM(amount) AS total_revenue,
COUNT(order_id) AS order_count
FROM Orders
GROUP BY
FORMAT(date, 'yyyy-MM');
19. Rank employees by salary within
each department.
SELECT customer_id
FROM Orders
WHERE YEAR(order_date) = 2023
GROUP BY customer_id
HAVING COUNT(DISTINCT
FORMAT(order_date,'yyyy-MM')) = 12
21. Find moving average of sales over
the last 3 days.
SELECT order_date,
AVG(total_amount) OVER (ORDER BY
order_date ROWS BETWEEN 2 PRECEDING
AND CURRENT ROW) AS moving_avg
FROM Orders;
22. Identify the first and last order
date for each customer.
SELECT customer_id,
MIN(order_date) AS first_order,
MAX(order_date) AS last_order
FROM Orders
GROUP BY customer_id;
23. Show product sales distribution
(percent of total revenue).
WITH TotalRevenue AS (
SELECT
SUM(quantity * price) AS total FROM Sales)
SELECT s.product_id,
SUM(s.quantity * s.price) AS revenue,
SUM(s.quantity * s.price) * 100/ t.total
AS revenue_pct
FROM Sales s
CROSS JOIN TotalRevenue t
GROUP BY s.product_id, t.total;
24. Retrieve customers who made
consecutive purchases (2 Days)
WITH cte AS (
SELECT id, order_date,
LAG(order_date) OVER (PARTITION BY id
ORDER BY order_date) AS prev_order_date
FROM Orders)
SELECT id, order_date, prev_odate
FROM cte
WHERE
DATEDIFF(DAY, prev_odate, order_date) = 1;
25. Find churned customers
(no orders in the last 6 months).
SELECT customer_id
FROM Orders
GROUP BY customer_id
HAVING
MAX(order_date) <
DATEADD(MONTH,-6,GETDATE());
26. Calculate cumulative revenue by
day.
SELECT order_date,
SUM(total_amount) OVER
(ORDER BY order_date) AS
cumulative_revenue
FROM Orders;
27. Identify top-performing
departments by average salary.
SELECT department_id,
AVG(salary) AS avg_salary
FROM Employee
GROUP BY department_id
ORDER BY avg_salary DESC;
28. Find customers who ordered
more than the average number of
orders per customer.
WITH customer_orders AS (
SELECT customer_id, COUNT(*) AS order_count
FROM Orders
GROUP BY customer_id)
SELECT * FROM customer_orders
WHERE order_count > (SELECT
AVG(order_count) FROM customer_orders);
29. Calculate revenue generated from
new customers (first-time orders).
WITH first_orders AS (
SELECT customer_id, MIN(order_date) AS
first_order_date FROM Orders
GROUP BY customer_id)
SELECT SUM(o.total_amount) AS new_revenue
FROM Orders o JOIN first_orders f
ON o.customer_id = f.customer_id
WHERE o.order_date = f.first_order_date;
30. Find the percentage of
employees in each department.
SELECT
department_id,
COUNT(*) AS emp_count,
COUNT(*) * 100.0 / (SELECT
COUNT(*) FROM Employee)
AS pct FROM Employee
GROUP BY department_id;
31. Retrieve the maximum salary
difference within each department.
SELECT
department_id,
MAX(salary) - MIN(salary) AS
salary_diff
FROM Employee
GROUP BY department_id;
32. Find products that contribute to
80% of the revenue (Pareto Principle).
WITH sales_cte AS (
SELECT product_id, SUM(qty * price) AS revenue
FROM Sales GROUP BY product_id),
total_revenue AS (
SELECT SUM(revenue) AS total FROM sales_cte)
SELECT s.product_id, s.revenue,
SUM(s.revenue) OVER
(ORDER BY s.revenue DESC ROWS BETWEEN UNBOUNDED
PRECEDING AND CURRENT ROW) AS running_total
FROM sales_cte s, total_revenue t
WHERE SUM(s.revenue) OVER (ORDER BY s.revenue DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW) <= t.total * 0.8;
33. Calculate average time between
two purchases for each customer.
WITH cte AS (
SELECT customer_id, order_date,
LAG(order_date) OVER (PARTITION BY
customer_id
ORDER BY order_date) AS prev_date
FROM Orders)
SELECT customer_id,
AVG(DATEDIFF(DAY, prev_date, order_date))
AS avg_gap_days FROM cte
WHERE prev_date IS NOT NULL
GROUP BY customer_id;
34. Show last purchase for each
customer along with order amount.
WITH ranked_orders AS
(SELECT customer_id, order_id,
total_amount, ROW_NUMBER() OVER
(PARTITION BY customer_id ORDER BY
order_date DESC) AS rn FROM Orders)
SELECT customer_id, order_id,
total_amount
FROM ranked_orders
WHERE rn = 1;
35. Calculate year-over-year growth
in revenue.
WITH income_cte AS (
SELECT salary,
SUM(salary) OVER (ORDER BY salary) AS
cum_incom,
COUNT(*) OVER() AS n,
ROW_NUMBER() OVER (ORDER BY salary) AS r
FROM Employee)
SELECT 1 - (2 * SUM((cum_income) / (SUM(salary)
OVER ()) * (1.0 / n)) ) AS gini_coefficient
FROM income_cte;
41. Compute the day when cumulative
revenue first exceeded 50% of total
revenue (median sales day).
SELECT
(SELECT PERCENTILE_CONT(0.25) WITHIN GROUP
(ORDER BY salary) OVER () FROM Employee) AS p25,
(SELECT PERCENTILE_CONT(0.50) WITHIN GROUP
(ORDER BY salary) OVER () FROM Employee) AS p50,
(SELECT PERCENTILE_CONT(0.75) WITHIN GROUP
(ORDER BY salary) OVER () FROM Employee) AS p75;
43. Retrieve customers with increasing
order amounts over their last 3 orders.
WITH cte AS (
SELECT customer_id, order_date, total_amount,
LAG(total_amount, 2) OVER (PARTITION BY
customer_id ORDER BY order_date) AS amt_t_minus_2,
LAG(total_amount, 1) OVER (PARTITION BY
customer_id ORDER BY order_date) AS amt_t_minus_1
FROM Orders)
SELECT customer_id, order_date, total_amount
FROM cte
WHERE amt_t_minus_2 < amt_t_minus_1
AND amt_t_minus_1 < total_amount;
44. Calculate conversion funnel
between different stages
→ →
(e.g., visits signups purchases).
SELECT
SUM(CASE WHEN stage = 'visit' THEN 1
ELSE 0 END) AS visits,
SUM(CASE WHEN stage = 'sign_up' THEN 1
ELSE 0 END) AS sign_ups,
SUM(CASE WHEN stage = 'purchase' THEN 1
ELSE 0 END) AS purchases
FROM Funnel;
45. Find the percentage of total sales
contributed by top 10% of customers.
WITH dept_avg AS (
SELECT department_id, AVG(salary) AS
avg_salary
FROM Employee
GROUP BY department_id)
SELECT e.* FROM Employee e JOIN dept_avg d
ON e.department_id = d.department_id
WHERE e.salary > d.avg_salary;
48. Calculate time between user
signup and their first purchase.
WITH first_purchase AS (
SELECT user_id, MIN(purchase_date) AS
first_purchase_date FROM Purchases
GROUP BY user_id)
SELECT u.user_id,
DATEDIFF(DAY, u.signup_date,
f.first_purchase_date) AS days_to_purchase
FROM Users u JOIN first_purchase f
ON u.user_id = f.user_id;
49. Retrieve the longest gap between
orders for each customer.
WITH cte AS (
SELECT customer_id, order_date,
LAG(order_date) OVER (PARTITION BY
customer_id ORDER BY order_date) AS
prev_order_date FROM Orders)
SELECT customer_id, MAX(DATEDIFF(DAY,
prev_order_date, order_date)) AS max_gap
FROM cte
WHERE prev_order_date IS NOT NULL
GROUP BY customer_id;
50. Identify customers with revenue
below the 10th percentile.
WITH cte AS (
SELECT customer_id, SUM(total_amount) AS
total_revenue
FROM Orders
GROUP BY customer_id)
SELECT customer_id, total_revenue
FROM cte
WHERE total_revenue <
(SELECT PERCENTILE_CONT(0.1) WITHIN GROUP
(ORDER BY total_revenue) FROM cte);