Setting OrderNumber of rows in a table

## Summary
A developer attempted to set sequential `OrderNumber` values for time zones, prioritizing US entries first (sorted alphabetically) followed by others (also alphabetically). The initial approach with `ROW_NUMBER()` failed due to improper partitioning/ordering and incorrect update logic.

## Root Cause
- The `ROW_NUMBER()` calculation in the subquery operated solely on the **subset of US time zones**, generating numbers only within that group (1 to 53).
- The `UPDATE` statement tried to assign this US-only numbering to US rows, but it erroneously attempted to set **all US rows** to a result set containing **multiple values**, causing an error.
- Non-US time zones were never assigned `OrderNumber` values.
## Why This Happens in Real Systems
- Partial data manipulation requirements (prioritizing a subset) are common but complex to implement in a single statement.
- Developers often misjudge scope boundaries when combining window functions with `UPDATE` operations.
- Time-zone/country prioritization logic is business-specific and prone to incorrect partitioning assumptions.
## Real-World Impact
- Time zone data failed to sort correctly in applications (UIs/dropdowns), placing US entries in arbitrary positions.
- Null `OrderNumber` values in non-US entries caused sorting errors or crashes.
- The broken `UPDATE` statement threw a SQL error (`Subquery returned more than 1 value`), halting execution.
## Example or Code
Fixed solution using a common table expression (CTE) and proper window function configuration:

```sql
WITH OrderedZones AS (
    SELECT Id,
           OrderNumber = ROW_NUMBER() OVER (
               ORDER BY CASE WHEN CountryId = 'US' THEN 0 ELSE 1 END, 
                        Id
           )
    FROM TimeZones
)
UPDATE tz
SET OrderNumber = o.OrderNumber
FROM TimeZones tz
JOIN OrderedZones o ON tz.Id = o.Id;

How Senior Engineers Fix It

  1. Repartitioning Logic: Avoid unnecessary partitioning—use a conditional ordering (CASE) to prioritize groups without fragmenting numbering.
  2. Single Pass Processing: Compute order numbers for all rows in one window function call using combined ordering:
    • US rows first (CASE forces CountryId='US' to sort as 0, others as 1).
    • Alphabetical sort (Id) within groups.
  3. Safe Update Pattern: Use a CTE/join for an unambiguous single-value-per-row update.
  4. Index Alignment: Leverage Id (primary key) for efficient CTE-to-table joins.

Why Juniors Miss It

  • Mistaking WHERE for Partitioning: Filtering subsets in subqueries (WHERE CountryId='US') breaks holistic numbering.
  • Window Function Misuse: Underestimating how unpartitioned ROW_NUMBER() paired with conditional sorting (CASE) solves ordering across groups.
  • Update Mechanics Ignorance: Attempting to set a column equal to a multi-row subquery causes runtime errors.
  • Over-Reliance on Step-by-Step Logic: Focusing on updating US/non-US groups separately instead of a single ordering operation.