Database Administrator MySQL Practice Problems with Real-World Scenarios & Solutions

Database Administrator MySQL Practice Problems with Real-World Scenarios & Solutions

Database Administrator MySQL Practice Problems with Real-World Scenarios & Solutions

Beginner Level Problems

1. Customer Database Query

Scenario:
You're working with an e-commerce database. The customers table contains: customer_id, name, email, join_date, and premium_member (boolean).

Problem:
Find all customers who joined in 2023 and are premium members.

Solution:

SELECT name, email 
FROM customers 
WHERE YEAR(join_date) = 2023 
AND premium_member = TRUE;

2. Inventory Management

Scenario:
Your products table tracks: product_id, name, category, price, and stock_quantity.

Problem:
List all electronics products with less than 50 items in stock, sorted by price (high to low).

Solution:

SELECT name, price 
FROM products 
WHERE category = 'Electronics' 
AND stock_quantity < 50 
ORDER BY price DESC;

Intermediate Level Problems

3. Hospital Patient Analysis

Scenario:
A hospital database has:

  • patients (patient_id, name, birth_date)

  • visits (visit_id, patient_id, visit_date, doctor_id)

  • doctors (doctor_id, name, specialty)

Problem:
Find patients who visited cardiologists more than twice in 2023.

Solution:

SELECT p.name, COUNT(*) AS cardiology_visits
FROM patients p
JOIN visits v ON p.patient_id = v.patient_id
JOIN doctors d ON v.doctor_id = d.doctor_id
WHERE d.specialty = 'Cardiology' 
AND YEAR(v.visit_date) = 2023
GROUP BY p.patient_id, p.name
HAVING COUNT(*) > 2;

4. University Course Enrollment

Scenario:
University database with:

  • students (student_id, name, major)

  • courses (course_id, title, department)

  • enrollments (enrollment_id, student_id, course_id, semester)

Problem:
Identify computer science courses with enrollment exceeding capacity (50 students) in Fall 2023.

Solution:

SELECT c.title, COUNT(*) AS enrolled_students
FROM courses c
JOIN enrollments e ON c.course_id = e.course_id
WHERE c.department = 'Computer Science'
AND e.semester = 'Fall2023'
GROUP BY c.course_id, c.title
HAVING COUNT(*) > 50;

Advanced Level Problems

5. Financial Transaction Analysis

Scenario:
Bank database with:

  • accounts (account_id, customer_id, balance, open_date)

  • transactions (transaction_id, account_id, amount, transaction_date, type)

Problem:
Find accounts with suspicious activity (3+ withdrawals over $5,000 in a 7-day period).

Solution:

SELECT a.account_id, c.name, COUNT(*) AS large_withdrawals
FROM accounts a
JOIN transactions t ON a.account_id = t.account_id
JOIN customers c ON a.customer_id = c.customer_id
WHERE t.type = 'withdrawal'
AND t.amount > 5000
GROUP BY a.account_id, c.name, t.transaction_date
HAVING COUNT(*) >= 3
AND DATEDIFF(MAX(t.transaction_date), MIN(t.transaction_date)) <= 7;

6. Airline Flight Optimization

Scenario:
Airline database tracks:

  • flights (flight_id, route_id, departure_time, arrival_time, aircraft_id)

  • routes (route_id, origin, destination, distance)

  • bookings (booking_id, flight_id, passenger_id, seat_class)

Problem:
Identify routes where business class occupancy is below 40% for the last quarter.

Solution:

WITH business_seats AS (
    SELECT 
        f.route_id,
        r.origin,
        r.destination,
        COUNT(CASE WHEN b.seat_class = 'Business' THEN 1 END) AS business_booked,
        (SELECT COUNT(*) FROM aircraft_seats WHERE aircraft_id = f.aircraft_id AND class = 'Business') AS total_business_seats
    FROM flights f
    JOIN routes r ON f.route_id = r.route_id
    JOIN bookings b ON f.flight_id = b.flight_id
    WHERE f.departure_time BETWEEN DATE_SUB(NOW(), INTERVAL 3 MONTH) AND NOW()
    GROUP BY f.route_id, r.origin, r.destination, f.aircraft_id
)
SELECT 
    origin, 
    destination,
    business_booked,
    total_business_seats,
    (business_booked/total_business_seats)*100 AS occupancy_rate
FROM business_seats
WHERE (business_booked/total_business_seats) < 0.4;

Expert Level Challenges

7. Retail Price Optimization

Scenario:
E-commerce database with:

  • products (product_id, name, current_price, cost)

  • sales (sale_id, product_id, sale_date, quantity, price_sold)

  • competitor_prices (comp_id, product_id, comp_price, date_recorded)

Problem:
Recommend price adjustments for products where:

  1. Our price is >20% higher than average competitor price

  2. Sales volume dropped >15% last month

  3. Current profit margin >30%

Solution:

WITH current_stats AS (
    SELECT 
        p.product_id,
        p.name,
        p.current_price,
        AVG(cp.comp_price) AS avg_comp_price,
        (p.current_price - p.cost)/p.current_price AS current_margin,
        SUM(CASE WHEN s.sale_date BETWEEN DATE_SUB(NOW(), INTERVAL 2 MONTH) AND DATE_SUB(NOW(), INTERVAL 1 MONTH) THEN s.quantity ELSE 0 END) AS prev_month_sales,
        SUM(CASE WHEN s.sale_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW() THEN s.quantity ELSE 0 END) AS last_month_sales
    FROM products p
    LEFT JOIN sales s ON p.product_id = s.product_id
    LEFT JOIN competitor_prices cp ON p.product_id = cp.product_id
    GROUP BY p.product_id, p.name, p.current_price, p.cost
)
SELECT 
    product_id,
    name,
    current_price,
    ROUND(avg_comp_price, 2) AS competitor_avg,
    ROUND(current_margin*100, 1) AS margin_percent,
    CASE 
        WHEN last_month_sales = 0 THEN -100 
        ELSE ROUND((last_month_sales-prev_month_sales)/prev_month_sales*100, 1) 
    END AS sales_change_percent,
    CONCAT('Recommended new price: $', ROUND(avg_comp_price*1.1, 2)) AS price_recommendation
FROM current_stats
WHERE current_price > avg_comp_price*1.2
AND ((last_month_sales-prev_month_sales)/prev_month_sales) < -0.15
AND current_margin > 0.3;

8. Smart City Traffic Analysis

Scenario:
City transportation database tracks:

  • traffic_sensors (sensor_id, location, highway, lane_count)

  • traffic_readings (reading_id, sensor_id, timestamp, speed, vehicle_count)

  • incidents (incident_id, location, start_time, end_time, severity)

Problem:
Create a traffic congestion early warning system that identifies:

  1. Locations with speed drop >30% compared to historical average

  2. Where vehicle count is >20% above average

  3. With no existing reported incidents

Solution:

WITH historical_avg AS (
    SELECT 
        sensor_id,
        AVG(speed) AS avg_speed,
        AVG(vehicle_count) AS avg_vehicles
    FROM traffic_readings
    WHERE timestamp BETWEEN DATE_SUB(NOW(), INTERVAL 3 MONTH) AND DATE_SUB(NOW(), INTERVAL 1 DAY)
    GROUP BY sensor_id
),
current_readings AS (
    SELECT 
        r.sensor_id,
        s.location,
        s.highway,
        r.speed,
        r.vehicle_count,
        h.avg_speed,
        h.avg_vehicles
    FROM traffic_readings r
    JOIN traffic_sensors s ON r.sensor_id = s.sensor_id
    JOIN historical_avg h ON r.sensor_id = h.sensor_id
    WHERE r.timestamp >= DATE_SUB(NOW(), INTERVAL 1 HOUR)
)
SELECT 
    cr.location,
    cr.highway,
    cr.speed AS current_speed,
    ROUND(cr.avg_speed, 1) AS historical_speed,
    cr.vehicle_count AS current_vehicles,
    ROUND(cr.avg_vehicles) AS historical_vehicles,
    CASE 
        WHEN (cr.avg_speed - cr.speed)/cr.avg_speed > 0.3 
        AND (cr.vehicle_count - cr.avg_vehicles)/cr.avg_vehicles > 0.2
        THEN 'CONGESTION WARNING'
        ELSE 'Normal'
    END AS status
FROM current_readings cr
WHERE NOT EXISTS (
    SELECT 1 FROM incidents i
    WHERE i.location = cr.location
    AND i.end_time IS NULL
)
HAVING status = 'CONGESTION WARNING';

Key Features of These Scenarios

 Real-world business cases from multiple industries
 Progressive difficulty with complete solutions
 Practical SQL techniques for data analysis
 Optimized queries following best practices
 Comprehensive scenarios with multiple tables