Running Node Pairs

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

Problem

In infra_nodes, a live node's status is stored as both 'running' and 'Running', and both mean the node is up. For failover coverage we need each pair of hostnames that both have a running node in the same region, listed once with the alphabetically-earlier hostname first. Sort by region, then by that first hostname, and within each first hostname list its partners from last to first.

Two servers, same region, both alive.

Tables

infra_nodes

Columns: node_id INTEGER, hostname TEXT, region TEXT, node_type TEXT, cpu_pct REAL, mem_pct REAL, status TEXT

infra_nodes: 10 of 200 rows
node_idhostnameregionnode_typecpu_pctmem_pctstatus
1037web-02us-west-2memory1319stopped
1074api-01eu-west-1storage2638draining
1111api-02sa-east-1gpu3957offline
1148db-primaryeu-central-1general5276Running
1185db-replicaus-east-1compute6595STOPPED
1222cache-01us-west-2memory7814running
1259worker-01eu-west-1StorageNULLNULLstopped
1296worker-02ap-south-1gpu452draining
1333gpu-node-01eu-central-1general1771offline
1370WEB-03us-east-1compute3090Running

Expected output

First 5 of 30 rows
regionhost_1host_2
ap-south-1WEB-03web-01
eu-central-1WEB-03web-01
eu-west-1WEB-03web-01
us-east-1WEB-03web-01
us-west-2WEB-03web-01

Worked solution and explanation

What this really asks

This is a self-join in disguise: 'which hosts run side by side' means joining infra_nodes to itself on region and reading off the hostname pairs. Three moves separate a clean answer from a mess. Normalize the casing before you filter with LOWER(status); use an INEQUALITY in the join with a.hostname < b.hostname so a host never pairs with itself and no pairing shows up in both directions; and keep DISTINCT, because hostnames recur across nodes in a region, so the join emits the same pairing once per matching pair of running nodes. Drop the LOWER and you silently lose every 'Running' node; drop the inequality and each pairing doubles alongside a spurious same-host row; drop DISTINCT and one pairing repeats several times over.


Building it

Step 1: Normalize the status before you filter

The live state lives in status as mixed casing ('running' and 'Running'), so an exact = 'running' match quietly keeps only the lowercase rows. Wrap both sides in LOWER(...) and compare to 'running' so the filter sees every live node.

Step 2: Self-join on region with an inequality

Join infra_nodes to itself on a.region = b.region so both rows sit in the same region, then add a.hostname < b.hostname to the join. That inequality is doing two jobs: it removes the host-matched-with-itself row and it keeps a single direction of each pairing, so ('cache-01','web-01') appears but ('web-01','cache-01') does not.

Step 3: Collapse the node-level fan-out with DISTINCT

Hostnames are not unique within a region, so the same pairing comes back once for every matching pair of running nodes. SELECT DISTINCT collapses those node-level matches down to one row per hostname pairing. Here it changes the answer, not just its tidiness: without it the row count balloons far past the real pairings.

Step 4: Order region, then first host, then partner descending

Order by region, then host_1 alphabetically, then host_2 DESC so each first host's partners read from last to first. Sort on the projected aliases host_1 and host_2, not on a.hostname / b.hostname: both underlying columns are literally named hostname, so a partner key written as b.hostname resolves back onto the first host and its direction stops mattering. The descending tail is what the ordering commits to beyond the region and first-host grouping, so it has to land on host_2.


The solution

Distinct co-located running host pairs per region
SELECT DISTINCT a.region, a.hostname AS host_1, b.hostname AS host_2
FROM infra_nodes a
INNER JOIN infra_nodes b ON a.region = b.region AND a.hostname < b.hostname
WHERE LOWER(a.status) = 'running' AND LOWER(b.status) = 'running'
ORDER BY a.region, host_1, host_2 DESC

Common follow-up questions