cswork / libraryOpen practice workspace

Coding questions · TikTok

Compute CTR drop with exclusions

This question evaluates a candidate's ability to compute time-windowed click-through rates using SQL aggregations, joins, filters and data-cleaning (excluding suspicious ads) while handling edge cases such as missing days, minimum-impression thresholds, division-by-zero, and integer-division pitfalls.

Assume today = 2025-09-01. Using ad delivery logs, find advertisers whose CTR in the last 7 days (2025-08-25 to 2025-08-31) dropped by at least 20% relative to the previous 7 days (2025-08-18 to 2025-08-24), after excluding suspicious ads. Return advertiser_id, last7_ctr, prev7_ctr, rel_drop (as a positive fraction), ordered by rel_drop DESC. Enforce that both windows have >= 10,000 impressions per advertiser after exclusions. Treat missing days as 0, guard against division-by-zero and integer division. Schema and small samples:

Table: advertisers(advertiser_id INT, name TEXT, vertical TEXT)

+---------------+----------+-----------+
| advertiser_id | name | vertical |
+---------------+----------+-----------+
| 101 | Acme Co | Gaming |
| 102 | Beta LLC | Ecommerce |
+---------------+----------+-----------+

Table: ad_events(date DATE, advertiser_id INT, ad_id INT, impressions INT, clicks INT, spend_cents INT)

+------------+---------------+-------+-------------+--------+-------------+
| date | advertiser_id | ad_id | impressions | clicks | spend_cents |
+------------+---------------+-------+-------------+--------+-------------+
| 2025-08-19 | 101 | 9001 | 5000 | 250 | 120000 |
| 2025-08-20 | 101 | 9001 | 5500 | 220 | 118000 |
| 2025-08-23 | 101 | 9001 | 4500 | 200 | 100000 |
| 2025-08-26 | 101 | 9001 | 7000 | 210 | 130000 |
| 2025-08-27 | 101 | 9002 | 5000 | 50 | 40000 |
| 2025-08-22 | 102 | 9100 | 14000 | 700 | 280000 |
| 2025-08-29 | 102 | 9100 | 15000 | 600 | 300000 |
| 2025-08-30 | 102 | 9101 | 8000 | 240 | 160000 |
+------------+---------------+-------+-------------+--------+-------------+
Table: suspicious_ads(ad_id INT)
+-------+
| ad_id |
+-------+
| 9002 |
+-------+

Write a single SQL query (ANSI SQL preferred) that produces the required output.

Compute advertiser CTR drop across two 7-day windows with suspicious-ad exclusions

You are given daily ad delivery logs and a list of suspicious ads to exclude.

Compute each advertiser's CTR (clicks / impressions) for:

  • Last 7 days: 2025-08-25 to 2025-08-31 (inclusive)
  • Previous 7 days: 2025-08-18 to 2025-08-24 (inclusive)

Exclude any rows whose ad_id appears in suspicious_ads before calculating impressions/clicks.

Return advertisers whose CTR in the last 7 days dropped by at least 20% relative to the previous 7 days. Define rel_drop as a positive fraction: rel_drop = (prev7_ctr - last7_ctr) / prev7_ctr

Requirements:

  • Return columns: advertiser_id, last7_ctr, prev7_ctr, rel_drop
  • Enforce that BOTH windows have at least 10,000 impressions per advertiser AFTER exclusions
  • Treat missing days as 0 (i.e., if there are no rows for a day, that day contributes 0 impressions/clicks)
  • Guard against division-by-zero and integer division
  • Order by rel_drop DESC

Write a single ANSI-SQL query.

Table advertisers

columntypeconstraints
advertiser_idINTPRIMARY KEY, NOT NULL
nameVARCHAR(100)NOT NULL
verticalVARCHAR(50)NOT NULL

Sample data:

advertiser_idnamevertical
101Acme CoGaming
102Beta LLCEcommerce

Table ad_events

columntypeconstraints
dateDATENOT NULL
advertiser_idINTNOT NULL
ad_idINTNOT NULL
impressionsINTNOT NULL
clicksINTNOT NULL
spend_centsINTNOT NULL

Sample data:

ad_idadvertiser_idclicksdateimpressionsspend_cents
90011012502025-08-195000120000
90011012202025-08-205500118000
90011012002025-08-234500100000
90011012102025-08-267000130000
9002101502025-08-27500040000
90011011202025-08-31400080000
91001027002025-08-2214000280000
91001026002025-08-2915000300000
91011022402025-08-308000160000

Table suspicious_ads

columntypeconstraints
ad_idINTPRIMARY KEY, NOT NULL

Sample data:

ad_id
9002

Expected output

One row per advertiser meeting the criteria, with CTRs computed over each 7-day window after excluding suspicious ads, and rel_drop >= 0.20. Ordered by largest relative drop first.

advertiser_idlast7_ctrprev7_ctrrel_drop
1010.030.0446670.328358
1020.0365220.050.269565

Hints

  1. Filter out suspicious ads first (e.g., LEFT JOIN suspicious_ads and keep only NULL matches).
  2. Use conditional aggregation (SUM(CASE WHEN date BETWEEN ... THEN ... END)) to compute window totals in one pass.
  3. Cast to DECIMAL and use NULLIF to avoid integer division and division-by-zero.