Break Through

A medium SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.

Domain
SQL
Difficulty
medium
Seniority
L3

Problem

The renewal list for next quarter's ad budget looks padded to the analyst signing it off, who wants to keep only the campaigns in ad_impressions where more than one in five impressions turned into a click. Surface those campaigns with their click-through rate and the revenue they brought in, highest click-through rate first.

A click is the only vote that counts.

Tables

ad_impressions

Columns: impression_id INTEGER, user_id INTEGER, ad_campaign TEXT, impression_time TEXT, clicked INTEGER, revenue REAL

ad_impressions: 10 of 200 rows
impression_iduser_idad_campaignimpression_timeclickedrevenue
253100BRAND_AWARENESS_Q12026-02-02 01:07:000NULL
306197PRODUCT_LAUNCH_X2026-03-03 02:14:000NULL
359294RETARGETING_CART2026-04-04 03:21:000NULL
412391HOLIDAY_PROMO2026-05-05 04:28:000NULL
465488NEW_USER_ACQU2026-06-06 05:35:0010.2
518NULLLOYALTY_PROGRAM2026-07-07 06:42:000NULL
571682FLASH_SALE_48H2026-08-08 07:49:000NULL
624779SUMMER_SALE_20242026-09-09 08:56:000NULL
677876BRAND_AWARENESS_Q12026-01-10 09:03:000NULL
730973PRODUCT_LAUNCH_X2026-02-11 10:10:0010.35

Expected output

First 5 of 6 rows
ad_campaignctr_pcttotal_revenueimpressions
LOYALTY_PROGRAM84.52215.3584
SUMMER_SALE_202433.3316.721
NEW_USER_ACQU26.674.415
FLASH_SALE_48H26.675.615
PRODUCT_LAUNCH_X25516

Worked solution and explanation

What this really is

Underneath the budget audit this is a ratio filtered by its own value. The click-through rate, SUM(clicked) over COUNT(*), does not exist until the rows are rolled up per ad_campaign, so the more-than-one-in-five bar has to judge the rolled-up rate, never a single impression. Candidates blow it two ways. Some filter in WHERE, where each row only carries a 0 or 1 flag. Others divide two integers, which floors every campaign below 100% to 0, so the bar drops all eight campaigns and the query returns nothing.


Build it in three moves

Step 1: Roll up per ad_campaign

Every metric here is a per-campaign number, so ad_impressions is grouped by ad_campaign first. COUNT(*) is the impressions served, including the many rows where revenue is NULL.

Step 2: Compute the rate in decimal

100.0 * SUM(clicked) / COUNT(*) gives the percentage. Summing the 0/1 clicked flag counts clicks, and the 100.0 forces decimal division. SUM(revenue) skips the NULLs on unclicked impressions, but those rows stay in the denominator.

Step 3: Judge the group, then sort

The bar runs in HAVING on the unrounded ratio, so rounding can never push a campaign across the line. The output rounds to two decimals and lists the highest rate first. FLASH_SALE_48H and NEW_USER_ACQU both sit at 26.67, and either may come first.

The solution

CTR per campaign with a group-level bar
SELECT
    ad_campaign,
    ROUND(100.0 * SUM(clicked) / COUNT(*), 2) AS ctr_pct,
    SUM(revenue) AS total_revenue,
    COUNT(*) AS impressions
FROM ad_impressions
GROUP BY ad_campaign
HAVING 100.0 * SUM(clicked) / COUNT(*) > 20
ORDER BY ctr_pct DESC
Filtering impressions
WHERE clicked = 1 keeps only clicked rows. Every surviving campaign then shows a 100% rate, and impressions quietly counts clicks.
Filtering campaigns
HAVING 100.0 * SUM(clicked) / COUNT(*) > 20 judges each campaign's full rate. Six of the eight campaigns clear it.

Common follow-up questions