SQL QUESTIONS FOR INTERVIEW
----------------------------------------------------------------------------
1. First Purchase Date & Total Purchases per Customer
Input Table: transactions
customer_id purchase_date transaction_id
C1 2024-01-10 T001
C1 2024-01-15 T002
C2 2024-02-01 T003
C1 2024-02-20 T004
C2 2024-03-05 T005
Query:
SELECT
customer_id,
MIN(purchase_date) AS first_purchase_date,
COUNT(*) AS total_purchases
FROM transactions
GROUP BY customer_id;
Output:
customer_id first_purchase_date total_purchases
C1 2024-01-10 3
C2 2024-02-01 2
2. Most Frequent Transaction Amount
Input Table: transactions
transaction_id amount
T001 100
T002 150
T003 100
T004 100
T005 150
Query:
SELECT amount
FROM (
SELECT amount, COUNT(*) AS freq
FROM transactions
GROUP BY amount
ORDER BY freq DESC
LIMIT 1
) AS freq_table;
Output:
amount
100
3. Top 3 Departments by Avg Salary
Input Table: employees
emp_id department salary
1 HR 50000
2 IT 80000
3 IT 85000
4 Sales 60000
5 Sales 62000
6 Finance 75000
Query:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC
LIMIT 3;
Output:
department avg_salary
IT 82500
Finance 75000
Sales 61000
4. Customers with Orders in ≥3 Different Months
Input Table: orders
customer_id order_date
C1 2024-01-15
customer_id order_date
C1 2024-02-20
C1 2024-03-05
C2 2024-01-10
C2 2024-02-15
Query:
SELECT customer_id
FROM (
SELECT customer_id, COUNT(DISTINCT EXTRACT(MONTH FROM order_date)) AS
month_count
FROM orders
GROUP BY customer_id
) AS monthly_orders
WHERE month_count >= 3;
Output:
customer_id
C1
5. Month-Over-Month Sales Growth
Input Table: sales
sale_date amount
2024-01-10 1000
2024-01-25 2000
2024-02-15 3500
sale_date amount
2024-03-05 4000
Query:
WITH monthly_sales AS (
SELECT
DATE_TRUNC('month', sale_date) AS month,
SUM(amount) AS total_sales
FROM sales
GROUP BY month
),
sales_with_lag AS (
SELECT
month,
total_sales,
LAG(total_sales) OVER (ORDER BY month) AS previous_sales
FROM monthly_sales
SELECT
month,
total_sales,
previous_sales,
ROUND(((total_sales - previous_sales) / previous_sales) * 100, 2) AS growth_percent
FROM sales_with_lag
WHERE previous_sales IS NOT NULL;
Output:
month total_sales previous_sales growth_percent
2024-02-01 3500 3000 16.67
2024-03-01 4000 3500 14.29
6. Employees with Same Designation & Join Date
Input Table: employees
emp_id designation join_date
1 Analyst 2022-01-10
2 Analyst 2022-01-10
3 Manager 2022-03-12
4 Analyst 2022-01-15
Query:
SELECT *
FROM employees
WHERE (designation, join_date) IN (
SELECT designation, join_date
FROM employees
GROUP BY designation, join_date
HAVING COUNT(*) > 1
);
Output:
emp_id designation join_date
1 Analyst 2022-01-10
emp_id designation join_date
2 Analyst 2022-01-10
7. Max Streak of Present Days per Employee
Input Table: attendance
employee date status
A1 2024-01-01 PRESENT
A1 2024-01-02 PRESENT
A1 2024-01-03 ABSENT
A1 2024-01-04 PRESENT
A1 2024-01-05 PRESENT
Query:
WITH marked AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY employee ORDER BY date) -
SUM(CASE WHEN status = 'PRESENT' THEN 1 ELSE 0 END)
OVER (PARTITION BY employee ORDER BY date) AS grp
FROM attendance
),
present_streaks AS (
SELECT employee, COUNT(*) AS streak
FROM marked
WHERE status = 'PRESENT'
GROUP BY employee, grp
)
SELECT employee, MAX(streak) AS max_streak
FROM present_streaks
GROUP BY employee;
Output:
employee max_streak
A1 2
8. Products Sold Every Day in a Given Week
Input Table: sales
product_id sale_date
P1 2024-06-10
P1 2024-06-11
P1 2024-06-12
P1 2024-06-13
P1 2024-06-14
P1 2024-06-15
P1 2024-06-16
P2 2024-06-10
P2 2024-06-12
P2 2024-06-14
Query:
SELECT product_id
FROM sales
WHERE sale_date BETWEEN '2024-06-10' AND '2024-06-16'
GROUP BY product_id
HAVING COUNT(DISTINCT sale_date) = 7;
Output:
product_id
P1
9. Users Who Logged In at Same Time on ≥3 Days
Input Table: logins
user_id login_time
U1 2024-06-01 09:00:00
U1 2024-06-02 09:00:00
U1 2024-06-03 09:00:00
U2 2024-06-01 10:00:00
U2 2024-06-02 10:05:00
Query:
SELECT user_id, TO_CHAR(login_time, 'HH24:MI:SS') AS login_clock, COUNT(DISTINCT
DATE(login_time)) AS login_days
FROM logins
GROUP BY user_id, TO_CHAR(login_time, 'HH24:MI:SS')
HAVING COUNT(DISTINCT DATE(login_time)) >= 3;
Output:
user_id login_clock login_days
U1 09:00:00 3
10. Employees earning more than dept average but less
than company average
Input Table: employees
emp_id name salary department
1 A 50000 HR
2 B 70000 HR
3 C 80000 IT
4 D 90000 IT
5 E 100000 Finance
Query:
WITH dept_avg AS (
SELECT department, AVG(salary) AS dept_avg_salary
FROM employees
GROUP BY department
),
company_avg AS (
SELECT AVG(salary) AS company_avg_salary FROM employees
SELECT e.*
FROM employees e
JOIN dept_avg d ON e.department = d.department
JOIN company_avg c
WHERE e.salary > d.dept_avg_salary AND e.salary < c.company_avg_salary;
Output:
emp_id name salary department
2 B 70000 HR
3 C 80000 IT
11. Quarter-over-Quarter Revenue Change
Input Table: sales
sale_date revenue
2024-01-15 1000
2024-02-15 2000
2024-04-15 3000
2024-05-15 5000
Query:
WITH sales_qtr AS (
SELECT
DATE_PART('quarter', sale_date) AS qtr,
DATE_PART('year', sale_date) AS yr,
SUM(revenue) AS total_revenue
FROM sales
GROUP BY yr, qtr
),
qtr_change AS (
SELECT *,
LAG(total_revenue) OVER (ORDER BY yr, qtr) AS prev_revenue
FROM sales_qtr
SELECT
yr, qtr, total_revenue, prev_revenue,
ROUND(((total_revenue - prev_revenue) / prev_revenue) * 100, 2) AS pct_change
FROM qtr_change
WHERE prev_revenue IS NOT NULL;
Output:
yr qtr total_revenue prev_revenue pct_change
2024 2 8000 3000 166.67
12. Products bought in 2 consecutive months
Input Table: orders
product_id order_date
P1 2024-01-15
P1 2024-02-10
P2 2024-01-05
P2 2024-03-05
Query:
WITH prod_months AS (
SELECT product_id, EXTRACT(YEAR FROM order_date)*12 + EXTRACT(MONTH FROM
order_date) AS month_num
FROM orders
GROUP BY product_id, order_date
),
ranked_months AS (
SELECT product_id, month_num,
LEAD(month_num) OVER (PARTITION BY product_id ORDER BY month_num) AS
next_month
FROM prod_months
SELECT DISTINCT product_id
FROM ranked_months
WHERE next_month - month_num = 1;
Output:
product_id
P1
13. Pairs of Customers Ordering Same Product on Same
Date
Input Table: orders
customer_id product_id order_date
C1 P1 2024-01-01
C2 P1 2024-01-01
C3 P2 2024-01-02
C2 P1 2024-01-03
Query:
SELECT a.customer_id AS customer1, b.customer_id AS customer2,
a.product_id, a.order_date
FROM orders a
JOIN orders b
ON a.product_id = b.product_id
AND a.order_date = b.order_date
AND a.customer_id < b.customer_id;
Output:
customer1 customer2 product_id order_date
C1 C2 P1 2024-01-01
14. Customers with Exactly 3 Purchases in Last 6 Months
Input Table: transactions
customer_id transaction_date
C1 2024-06-01
C1 2024-05-15
C1 2024-04-10
C2 2024-03-01
C2 2024-06-02
Query:
SELECT customer_id
FROM transactions
WHERE transaction_date >= CURRENT_DATE - INTERVAL '6 months'
GROUP BY customer_id
HAVING COUNT(*) = 3;
Output:
customer_id
C1
15. Second Highest Revenue Product in Each Category
Input Table: products
product_id category revenue
P1 A 1000
P2 A 2000
P3 A 3000
P4 B 500
P5 B 1500
Query:
SELECT category, product_id, revenue
FROM (
SELECT *,
DENSE_RANK() OVER (PARTITION BY category ORDER BY revenue DESC) AS rnk
FROM products
) ranked
WHERE rnk = 2;
Output:
category product_id revenue
A P2 2000
category product_id revenue
B P4 500
16. Dates When >80% Employees Were Present
Input Table: attendance
emp_id date status
E1 2024-06-01 PRESENT
E2 2024-06-01 PRESENT
E3 2024-06-01 ABSENT
E1 2024-06-02 PRESENT
E2 2024-06-02 PRESENT
E3 2024-06-02 PRESENT
Query:
WITH total_emps AS (
SELECT COUNT(DISTINCT emp_id) AS total_emp FROM attendance
),
daily_attendance AS (
SELECT date,
SUM(CASE WHEN status = 'PRESENT' THEN 1 ELSE 0 END) AS present_count
FROM attendance
GROUP BY date
SELECT d.date
FROM daily_attendance d
CROSS JOIN total_emps t
WHERE (present_count * 1.0 / t.total_emp) > 0.8;
Output:
date
2024-06-02
17. Employees with No Absence
Input Table: attendance
emp_id date status
E1 2024-06-01 PRESENT
E2 2024-06-01 ABSENT
E1 2024-06-02 PRESENT
E2 2024-06-02 PRESENT
Query:
SELECT emp_id
FROM attendance
GROUP BY emp_id
HAVING SUM(CASE WHEN status = 'ABSENT' THEN 1 ELSE 0 END) = 0;
Output:
emp_id
E1
18. Departments Hiring >3 Employees in Last Quarter
Input Table: employees
emp_id department hire_date
1 HR 2024-03-01
2 HR 2024-04-01
3 HR 2024-05-01
4 HR 2024-05-15
5 IT 2024-04-01
Query:
SELECT department
FROM employees
WHERE hire_date >= DATE_TRUNC('quarter', CURRENT_DATE - INTERVAL '1 quarter')
GROUP BY department
HAVING COUNT(*) > 3;
Output:
department
HR
19. Deduplicate Orders (Same Customer, Product,
Amount, Date)
Input Table: orders
order_id customer_id product_id amount order_date
O1 C1 P1 100 2024-06-01
O2 C1 P1 100 2024-06-01
order_id customer_id product_id amount order_date
O3 C2 P2 200 2024-06-02
Query (retain 1 row per duplicate group):
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id, product_id, amount, order_date
ORDER BY order_id
) AS rn
FROM orders
) deduped
WHERE rn = 1;
Output:
order_id customer_id product_id amount order_date
O1 C1 P1 100 2024-06-01
O3 C2 P2 200 2024-06-02