← PayPal Interview Insights

PayPal·Data Scientist·Technical Phone Screen·Senior

SeniorPrefer not to say
Jul 2026Remote

Summary

Got a take-home style SQL case for a Data Scientist role on PayPal's fraud side. The problem was dense, like genuinely one of the harder SQL prompts I've seen in an interview context, and it tested whether you actually understand window functions and time-based filtering or just know how to write basic joins.

Questions Asked (1)

Q1

You're on a fraud detection team. Write a single SQL query that identifies candidate account takeover events in the last 7 days. A candidate event requires: the user's first successful login from a new device or new IP in the prior 30 days, followed within 2 hours by a transfer over $500 to a first-time recipient. Exclude users whose accounts are less than 7 days old at login time. If multiple transfers match the same login, keep only the earliest. Return specific output columns including a reason code, and at the end recommend indexes to support the query on a PostgreSQL-like warehouse.

Data ModelingProduct Analytics & MetricsTechnical Trade-offs
Author's notes

This one took me a while to decompose.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Break the problem into two CTEs: one for qualifying logins (first successful login from a new device/IP in the prior 30 days, excluding accounts <7 days old) and one for qualifying transfers (>$500 to a first-time recipient within 2 hours of login). Join them on user_id with a time window, deduplicate to keep the earliest transfer per login, and assign a reason code. Finally, recommend indexes on the join and filter columns to optimize performance.

Pro tip: Explicitly state your assumptions about 'first-time recipient' (e.g., no prior transfers to that recipient in the last 30 days) and 'new device/IP' (e.g., not seen in the user's history in the prior 30 days), as these definitions can vary. Also, mention that you would validate the query with a small sample and consider edge cases like timezone handling and NULL values.

1. Define qualifying logins

Create a CTE that selects successful logins in the last 7 days where the device_id and ip_address are new for the user in the prior 30 days, and the account is at least 7 days old at login time.

2. Define qualifying transfers

Create a CTE that selects transfers over $500 to a recipient not previously sent to by the user (first-time recipient), along with the transfer timestamp and recipient_id.

3. Join and filter by time window

Join the qualifying logins and transfers on user_id where the transfer occurs within 2 hours after the login. Use a window function to rank transfers per login by transfer time and keep only the earliest.

4. Format output and assign reason code

Select the required columns (e.g., user_id, login_time, transfer_time, device_id, ip_address, amount, recipient_id) and add a reason code like 'ACCOUNT_TAKEOVER' or 'NEW_DEVICE_NEW_IP_TRANSFER'.

5. Recommend indexes

Suggest indexes on login_events(user_id, login_time, success, device_id, ip_address) and transfers(user_id, transfer_time, amount, recipient_id) to speed up filtering and joins.

Key Points to Mention

  • Use of CTEs for readability and modularity
  • Definition of 'new device/IP' as not seen in the prior 30 days for that user
  • Definition of 'first-time recipient' as no prior transfers to that recipient in the last 30 days
  • Use of window functions (e.g., ROW_NUMBER) to deduplicate transfers per login
  • Time window join condition: transfer_time BETWEEN login_time AND login_time + INTERVAL '2 hours'
  • Index recommendations on join and filter columns to optimize performance

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.