Amazon and Microsoft asked these SQL questions in their interview.
1/ Find the second highest salary without using LIMIT, OFFSET, or TOP.
2/ Identify customers who made transactions in every month of the year.
3/ Calculate the 7-day moving average of sales for each product.
4/ Find users who logged in for at least three consecutive days.
5/ Use window functions to rank orders by order value per customer and return the top 3.
6/ Retrieve employees who earn more than their managers.
7/ Find duplicate rows in a large table and delete only the extras.
8/ Optimize a slow-performing query with multiple joins and aggregations.
9/ Get the first order for each customer, handling tie-breakers properly.
10/ Find products never purchased by any customer.
11/ Retrieve users who made purchases in 2 consecutive months but not the 3rd.
12/ Find the department with the highest total salary payout.
13/ Identify employees with the same salary in the same department.
14/ Calculate median salary without using built-in functions.
15/ Write a query to pivot rows into monthly sales columns.
16/ Identify top N customers with the highest total purchases (with tie handling).
17/ Get the running total of revenue per day using window functions.
18/ Find users whose most frequently purchased category in the last year is ‘Electronics’.
19/ Retrieve the first and last event for each user from an events table.
20/ Rank products by yearly sales, resetting rank every new year.
Solve these questions and test your SQL skills.
-- ------------------------------------------
-- SAMPLE DATASETS + SQL INTERVIEW QUERIES
-- For 2+ years experience (Amazon, Microsoft)
-- ------------------------------------------
-- ==========================================
-- TABLE 1: Employee (Q1, Q6, Q13, Q14)
-- ==========================================
CREATE TABLE Employee (
emp_id INT PRIMARY KEY,
salary INT,
manager_id INT,
dept_id INT
);
INSERT INTO Employee VALUES
(1, 100000, NULL, 1),
(2, 90000, 1, 1),
(3, 90000, 1, 1),
(4, 80000, 2, 1),
(5, 70000, 2, 2),
(6, 70000, 3, 2);
-- ==========================================
-- TABLE 2: Customers & Transactions (Q2)
-- ==========================================
CREATE TABLE Customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE Transactions (
txn_id INT PRIMARY KEY,
customer_id INT,
amount INT,
txn_date DATE
);
INSERT INTO Customers VALUES (1, 'Alice'), (2, 'Bob');
INSERT INTO Transactions VALUES
(1, 1, 100, '2024-01-15'),
(2, 1, 200, '2024-02-15'),
(3, 1, 150, '2024-03-10'),
(4, 1, 175, '2024-04-20'),
(5, 1, 125, '2024-05-22'),
(6, 1, 100, '2024-06-01'),
(7, 1, 300, '2024-07-09'),
(8, 1, 180, '2024-08-13'),
(9, 1, 210, '2024-09-05'),
(10, 1, 130, '2024-10-29'),
(11, 1, 120, '2024-11-11'),
(12, 1, 250, '2024-12-10'),
(13, 2, 100, '2024-01-01'),
(14, 2, 200, '2024-02-15'),
(15, 2, 150, '2024-04-10');
-- ==========================================
-- TABLE 3: Sales (Q3, Q15, Q17, Q20)
-- ==========================================
CREATE TABLE Sales (
product_id INT,
sales_date DATE,
qty INT
);
INSERT INTO Sales VALUES
(101, '2024-01-01', 10),
(101, '2024-01-02', 5),
(101, '2024-01-08', 8),
(101, '2024-01-09', 9),
(102, '2024-01-01', 2),
(102, '2024-01-04', 7),
(102, '2024-01-05', 6);
-- ==========================================
-- TABLE 4: Logins (Q4)
-- ==========================================
CREATE TABLE Logins (
user_id INT,
login_date DATE
);
INSERT INTO Logins VALUES
(1, '2024-01-01'),
(1, '2024-01-02'),
(1, '2024-01-03'),
(1, '2024-01-05'),
(2, '2024-01-01'),
(2, '2024-01-03'),
(2, '2024-01-04');
-- ==========================================
-- TABLE 5: Orders & OrderItems (Q5, Q8, Q9, Q10, Q12, Q16)
-- ==========================================
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
amount INT
);
CREATE TABLE OrderItems (
order_id INT,
product_id INT,
qty INT,
unit_price INT
);
INSERT INTO Orders VALUES
(1001, 1, '2024-01-01', 200),
(1002, 1, '2024-01-05', 300),
(1003, 2, '2024-01-03', 400);
INSERT INTO OrderItems VALUES
(1001, 101, 1, 200),
(1002, 102, 2, 150),
(1003, 103, 4, 100);
-- ==========================================
-- TABLE 6: Products (Q8, Q10, Q18)
-- ==========================================
CREATE TABLE Products (
product_id INT PRIMARY KEY,
name VARCHAR(50),
category VARCHAR(50)
);
INSERT INTO Products VALUES
(101, 'Phone', 'Electronics'),
(102, 'TV', 'Electronics'),
(103, 'T-Shirt', 'Clothing'),
(104, 'Headphones', 'Electronics'),
(105, 'Shoes', 'Footwear');
-- ==========================================
-- TABLE 7: Purchases (Q11, Q18)
-- ==========================================
CREATE TABLE Purchases (
user_id INT,
product_id INT,
purchase_date DATE
);
INSERT INTO Purchases VALUES
(1, 101, '2024-01-15'),
(1, 102, '2024-02-15'),
(1, 103, '2024-04-10'),
(2, 101, '2024-01-01'),
(2, 105, '2024-03-01');
-- ==========================================
-- TABLE 8: Events (Q19)
-- ==========================================
CREATE TABLE Events (
id INT,
user_id INT,
event_ts TIMESTAMP
);
INSERT INTO Events VALUES
(1, 1, '2024-01-01 09:00:00'),
(2, 1, '2024-01-05 10:00:00'),
(3, 2, '2024-01-02 14:00:00'),
(4, 2, '2024-01-04 16:00:00');
Solutions and Queries
1. Second Highest Salary (no LIMIT/OFFSET/TOP)
Table: Employee(id, salary)
Explanation: Find the highest salary in the subquery, then get the max salary below it.
2. Customers with Transactions Every Month
Tables: Customers(id), Transactions(id, customer_id, amount, txn_date)
Explanation: Generate months 1–12, ensure each appears for each customer.
3. 7-Day Moving Average of Sales per Product
Table: Sales(product_id, sales_date, qty)
Explanation: Use window frame to average current + past 6 days.
4. Users Logged in for ≥3 Consecutive Days
Table: Logins(user_id, login_date)
Explanation: Consecutive-date grouping using "gaps and islands".
5. Top 3 Orders by Value per Customer (Window Functions)
Table: Orders(order_id, customer_id, amount)
Explanation: Partition by customer, rank by order amount.
6. Employees Earning More Than Their Managers
Table: Employees(emp_id, manager_id, salary)
7. Find and Delete Duplicate Rows (Keep One)
Table: T(id, col1, col2, ...)
8. Optimize Slow Query with Joins + Aggregations
Scenario:
Optimizations:
-
Index on
Products(category) -
Composite index on
OrderItems(order_id, product_id) -
Rewrite using derived pre-agg:
9. First Order per Customer (with tie-breakers)
Table: Orders(order_id, customer_id, order_date, order_id)
10. Products Never Purchased
Tables: Products(product_id), OrderItems(order_id, product_id, ...)
11. Users Purchased in 2 Consecutive Months but Not 3rd
Table: Purchases(user_id, purchase_date)
12. Department with Highest Total Salary
Table: Employees(emp_id, dept_id, salary)
13. Employees with Same Salary in Same Department
14. Median Salary (no built-in)
15. Pivot Rows → Monthly Sales
Table: Sales(product_id, sales_date, qty)
Or use PIVOT in DBs that support it (e.g., SQL Server).
16. Top N Customers by Total Purchases (with ties)
17. Running Total of Revenue per Day
Table: Orders(order_id, order_date, amount)
18. Users’ Most Frequent Category = ‘Electronics’ in Last Year
Tables: Purchases(user_id, product_id, purchase_date), Products(product_id, category)
19. First & Last Event per User
Table: Events(id, user_id, event_ts)
Or use ROW_NUMBER() twice:
20. Rank Products by Yearly Sales (Reset Annually)
Table: Sales(product_id, sales_date, qty)
Summary Table
Here's a quick reference for techniques used:
| Question | Technique(s) |
|---|---|
| 1, 14 | Aggregation + Subquery / Window Functions |
| 2, 11 | EXTRACT, date logic, CTE for consecutive periods |
| 3, 7, 17, 20 | Window functions |
| 4, 19 | Gap-and-island or window with row‑numbers |
| 5, 16 | RANK()/DENSE_RANK() |
| 6 | Self‑join |
| 8 | Indexing, refactoring, CTE optimization |
| 9 | ROW_NUMBER() with deterministic tie-break |
| 10 | LEFT JOIN ... IS NULL anti‑join |
| 12, 13 | Grouping + HAVING / ORDER BY |
| 15 | Conditional aggregation / pivot |
Comments
Post a Comment