Windows I — ranking & offsets
Concept  ·  SQL & Querying

On ties, ROW_NUMBER breaks them arbitrarily, RANK gaps, DENSE_RANK doesn't — only one matches the business sentence.

ROW_NUMBER always gives distinct numbers, so it breaks ties by whatever the ORDER BY leaves undecided. RANK gives tied rows the same rank and then skips; DENSE_RANK gives the same rank and doesn't skip. Only one matches 'ties share a place'.

See it break
entries
namescore
Ana90
Ben90
Cy80
The trap
SELECT
  name,
  ROW_NUMBER() OVER (
    ORDER BY
      score DESC,
      name
  ) AS place
FROM
  entries
ORDER BY
  place;
The fix
SELECT
  name,
  RANK() OVER (
    ORDER BY
      score DESC
  ) AS place
FROM
  entries
ORDER BY
  name;
INPUTYour queryThe fix
Ana11
Ben21
Cy33

Ana and Ben tied at 90 but the standings put Ben in second — ROW_NUMBER invented an order the scores don't have.

The rule

Pick the function by intent: RANK or DENSE_RANK when ties should share a place, ROW_NUMBER only when you truly want an arbitrary single winner per group.

DENSE_RANK() OVER (ORDER BY score DESC)
Shows up elsewhere
Top-N per group
Try one →Prove it in practice →