First Half of Page Views

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
L4
Asked in
Bosch

Problem

Which page views make up the first half of our page_views log by view ID, where half is measured against however many records the table holds in total? We want every detail of each of those views plus its position number, in view ID order.

Half the data. The first half.

Tables

page_views

Columns: view_id INTEGER, page_url TEXT, user_id INTEGER, referrer TEXT, dur_ms INTEGER, device TEXT, viewed_at TEXT

page_views: 10 of 200 rows
view_idpage_urluser_idreferrerdur_msdeviceviewed_at
5053/products1555amazon.com637desktop2026-09-02 01:09:00
5106/checkout1652twitter.com774tablet2026-09-03 02:18:00
5159/profile1749github.com911Mobile2026-09-04 03:27:00
5212/search1846NULL1048DESKTOP2026-09-05 04:36:00
5265/about1943reddit.com1185mobile2026-09-06 05:45:00
5318/blog/intro1555NULLNULLdesktop2026-09-07 06:54:00
5371/pricing1652bing.com1459tablet2026-09-08 07:03:00
5424/docs/api1749news.ycombinator.com1596Mobile2026-09-09 08:12:00
5477/settings1846NULL1733DESKTOP2026-09-10 09:21:00
5530/Home1943bing.com1870mobile2026-09-11 10:30:00

Expected output

First 5 of 100 rows
view_idpage_urluser_idreferrerdur_msdeviceviewed_atrn
5053/products1555amazon.com637desktop2026-09-02 01:09:001
5106/checkout1652twitter.com774tablet2026-09-03 02:18:002
5159/profile1749github.com911Mobile2026-09-04 03:27:003
5212/search1846NULL1048DESKTOP2026-09-05 04:36:004
5265/about1943reddit.com1185mobile2026-09-06 05:45:005

Worked solution and explanation

What this problem really is

This is a positional cut dressed up as a log export. The skill: number every view in view_id order and cut at a boundary the data itself supplies, half of whatever page_views holds right now. Anyone can sort by view_id. The trap is writing LIMIT 100 because the table happens to hold 200 rows, or filtering view_id <= something as if ids were contiguous. Do the first and you return no rn column and a cutoff that is wrong the day the table grows. Do the second and you grab the wrong rows outright: ids here step by 53 and later batches jump past ten million.


Break down the requirements

Step 1: Establish a deterministic position

ROW_NUMBER() OVER (ORDER BY view_id) numbers every row globally. Plain LIMIT n/2 is illegal in most engines when n is itself a subquery, and it would not give you a position to return alongside the other columns.

Step 2: Derive the cutoff

(SELECT COUNT(*) / 2 FROM page_views) is a scalar subquery evaluated once over the whole table. Integer division drops the middle row on an odd total, which is the implicit contract of a first half.

Step 3: Filter and re-order

WHERE rn <= cutoff keeps the lower half. The outer ORDER BY view_id is non-negotiable because the window's ORDER BY does not bind the order of the result set after a filter.


The solution

FIRST HALF BY ROW NUMBER
SELECT *
FROM (
    SELECT *,
           ROW_NUMBER() OVER (ORDER BY view_id) AS rn
    FROM page_views
) sub
WHERE rn <= (SELECT COUNT(*) / 2 FROM page_views)
ORDER BY view_id

Common follow-up questions

Common follow-up questions