CDN-Related DNS Lookups
An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- easy
- Seniority
- L3
- Asked in
- Oracle
Problem
The network team is tracking down CDN-related DNS resolution issues. Pull all lookup records where the domain contains 'cdn' regardless of casing.
DNS lookups tied to the CDN.
Tables
dns_lookups
Columns: lookup_id INTEGER, domain TEXT, rec_type TEXT, ttl_secs INTEGER, status TEXT, latency REAL, looked_at TEXT
| lookup_id | domain | rec_type | ttl_secs | status | latency | looked_at |
|---|---|---|---|---|---|---|
| 129 | cdn.example.com | AAAA | 47 | NXDOMAIN | 0.47 | 2026-02-02 01:03:00 |
| 158 | auth.example.com | CNAME | 64 | SERVFAIL | 0.84 | 2026-03-03 02:06:00 |
| 187 | search.example.com | MX | 81 | TIMEOUT | 1.21 | 2026-04-04 03:09:00 |
| 216 | db.internal.net | TXT | 98 | REFUSED | 1.58 | 2026-05-05 04:12:00 |
| 245 | cache.internal.net | NS | 115 | NOERROR | 1.95 | 2026-06-06 05:15:00 |
| 274 | example.com | A | 132 | NXDOMAIN | 2.32 | 2026-07-07 06:18:00 |
| 303 | www.example.com | AAAA | 149 | SERVFAIL | 2.69 | 2026-08-08 07:21:00 |
| 332 | API.example.com | CNAME | NULL | TIMEOUT | 3.06 | 2026-09-09 08:24:00 |
| 361 | Cdn.Example.Com | MX | 183 | REFUSED | 3.43 | 2026-01-10 09:27:00 |
| 390 | api.example.com | TXT | 200 | NOERROR | NULL | 2026-02-11 10:30:00 |
Expected output
| lookup_id | domain | rec_type | ttl_secs | status | latency | looked_at |
|---|---|---|---|---|---|---|
| 129 | cdn.example.com | AAAA | 47 | NXDOMAIN | 0.47 | 2026-02-02 01:03:00 |
| 361 | Cdn.Example.Com | MX | 183 | REFUSED | 3.43 | 2026-01-10 09:27:00 |
| 419 | cdn.example.com | NS | 217 | NXDOMAIN | 4.17 | 2026-03-12 11:33:00 |
| 651 | Cdn.Example.Com | AAAA | 353 | REFUSED | 7.13 | 2026-02-20 19:57:00 |
| 709 | cdn.example.com | MX | 387 | NXDOMAIN | 7.87 | 2026-04-22 21:03:00 |
Worked solution and explanation
This is a data-cleaning problem dressed up as a one-line filter. The domain column stores the same CDN host under two spellings, 'cdn.example.com' and 'Cdn.Example.Com', and the whole question is whether your match survives that. Anyone can write LIKE '%cdn%'; what separates candidates is normalizing the column before matching. Skip it and 20 of the 40 lookups vanish, and on this data every one of them is a REFUSED lookup (361, 651, 941 and on), exactly the failures the team is hunting.
Walking to the answer
Step 1: Look at the spellings before the filter
Scan the values in domain first. 'cdn.example.com' sits next to 'Cdn.Example.Com', and 'api.example.com' next to 'API.example.com'. Case is not a property you can trust on this column, so any match that depends on it is already wrong.
Step 2: Normalize the column, then match
Wrap the stored value: LOWER(domain) LIKE '%cdn%'. Lowercasing domain and comparing it against a lowercase pattern makes the test blind to however the host was typed in, so both spellings land in the result.
Step 3: Return the whole record
The team wants the lookups themselves, not a summary, so the projection is every column of dns_lookups. No order is asked for, so none is imposed.
SELECT *
FROM dns_lookups
WHERE LOWER(domain) LIKE '%cdn%'- Raw match
domain LIKE '%cdn%'keeps only the 20 'cdn.example.com' rows, every one NXDOMAIN. The list looks complete and contains no refusals at all.- Normalized match
LOWER(domain) LIKE '%cdn%'keeps all 40, including the 20 'Cdn.Example.Com' rows whosestatusis 'REFUSED'.
Common follow-up questions
- What is the difference between `ILIKE` and `LOWER()` plus `LIKE`? (`ILIKE` is a Postgres-family extension; `LOWER()` plus `LIKE` is portable across engines.)
- How would you keep this fast if it ran every hour over the full table? (Expression index on `LOWER(domain)`, trigram index for the leading wildcard, or a cleaned column written at ingest.)
- What if you only needed the latest lookup per CDN host? (Tests normalizing before grouping, so the two spellings collapse into one host instead of two.)