Audit and onboard unfamiliar datasets safely
Company: Expedia
Role: Data Scientist
Category: Data Manipulation (SQL/Python)
Difficulty: medium
Interview Round: Onsite
Overview: This question evaluates a data scientist's competency in dataset discovery, schema and key verification, profiling for distributions/missingness/timezones/currencies, duplicate and join-inflation detection, event-sequence validation, accurate metric computation, and the design of data-quality tests/data contracts within SQL/Python workflows.
Read the full Expedia Data Scientist interview experience this question came from
Search-to-booking funnel metrics with GMV and margin
Tables
searches(search_id INT, user_id INT, search_timestamp TIMESTAMP, checkin_date DATE, checkout_date DATE, num_adults INT, num_children INT, currency VARCHAR(3), locale VARCHAR(5))
impressions(impression_id INT, search_id INT, hotel_id INT, impression_timestamp TIMESTAMP, position INT)
clicks(click_id INT, search_id INT, hotel_id INT, click_timestamp TIMESTAMP)
bookings(booking_id INT, original_search_id INT, hotel_id INT, user_id INT, booking_timestamp TIMESTAMP, checkin_date DATE, checkout_date DATE, rooms INT, adults INT, children INT, currency VARCHAR(3), price DECIMAL(10,2), cost DECIMAL(10,2), property_currency VARCHAR(3), event_ingested_at TIMESTAMP)
cancellations(cancellation_id INT, booking_id INT, cancellation_timestamp TIMESTAMP, cancelled_rooms INT, refund_amount DECIMAL(10,2))
fx_rates(currency VARCHAR(3), rate_date DATE, rate_to_usd DECIMAL(10,4))
Hints
- Pre-aggregate impressions and clicks per search in separate CTEs to avoid many-to-many join inflation.
- To compute bookings within 7 days, join bookings to searches on original_search_id and filter by booking_timestamp BETWEEN search_timestamp AND search_timestamp + INTERVAL '7 days'.
Validate event sequencing and late-arriving bookings
Tables
searches(search_id INT, user_id INT, search_timestamp TIMESTAMP, checkin_date DATE, checkout_date DATE, num_adults INT, num_children INT, currency VARCHAR(3), locale VARCHAR(5))
impressions(impression_id INT, search_id INT, hotel_id INT, impression_timestamp TIMESTAMP, position INT)
clicks(click_id INT, search_id INT, hotel_id INT, click_timestamp TIMESTAMP)
bookings(booking_id INT, original_search_id INT, hotel_id INT, user_id INT, booking_timestamp TIMESTAMP, checkin_date DATE, checkout_date DATE, rooms INT, adults INT, children INT, currency VARCHAR(3), price DECIMAL(10,2), cost DECIMAL(10,2), property_currency VARCHAR(3), event_ingested_at TIMESTAMP)
cancellations(cancellation_id INT, booking_id INT, cancellation_timestamp TIMESTAMP, cancelled_rooms INT, refund_amount DECIMAL(10,2))
Hints
- Aggregate to the earliest impression, click, and cancellation per booking using MIN() in a CTE.
- Derive the flags by comparing the ordered timestamps and checking event_ingested_at against booking_timestamp + INTERVAL '2 days'.
Detect travel-specific booking pitfalls with data quality flags
Tables
bookings(booking_id INT, original_search_id INT, hotel_id INT, user_id INT, booking_timestamp TIMESTAMP, checkin_date DATE, checkout_date DATE, rooms INT, adults INT, children INT, currency VARCHAR(3), price DECIMAL(10,2), cost DECIMAL(10,2), property_currency VARCHAR(3), event_ingested_at TIMESTAMP)
cancellations(cancellation_id INT, booking_id INT, cancellation_timestamp TIMESTAMP, cancelled_rooms INT, refund_amount DECIMAL(10,2))
fx_rates(currency VARCHAR(3), rate_date DATE, rate_to_usd DECIMAL(10,4))
Hints
- Use a window function (COUNT OVER PARTITION BY user_id, hotel_id, checkin_date) to detect rebookings.
- Aggregate cancellations by booking_id and join FX rates at booking and check-in dates to derive partial cancellation and FX mismatch flags.