In this lesson, you will learn how to pinpoint exact moments when an entity transitions from one status to another using SQL window functions.
The Core Concept
Imagine you are tracking the status of support tickets: Open, Pending, or Resolved. To analyze how long tickets remain in a specific state, you first need to identify the exact rows where the status changes from the previous record. We achieve this by comparing a row's value to the one preceding it.
We use the LAG() window function to "peek" at the status of the previous row. By comparing this to the current row, we can create a "flag"—a logical 1 if the state changed, or 0 if it remained the same.
Practical Implementation
Assume we have a table ticket_history with ticket_id, status, and changed_at. We want to flag every time a ticket’s status flips.
SELECT
ticket_id,
status,
changed_at,
CASE
WHEN status <> LAG(status) OVER (PARTITION BY ticket_id ORDER BY changed_at)
THEN 1
ELSE 0
END AS is_state_change
FROM ticket_history;
In this query:
PARTITION BY ticket_idensures we only compare the current row to the previous status of that specific ticket.ORDER BY changed_atkeeps our timeline chronological.- The
CASEstatement acts as our logical trigger: if the current status doesn’t match the previous one, we assign a1(a flag indicating a change).
Why This Matters
This technique is the foundation for advanced lifecycle analysis. Once you have these flags, you can easily perform "State Duration" calculations. By summing these flags (or using them as groupings), you can isolate specific segments of a user’s or item’s journey, effectively turning a raw log of events into a clean history of state transitions. This approach is much more efficient than self-joining the table, as it processes the sequence in a single pass.
Key Takeaway: Use the LAG() function to compare current values against predecessors, allowing you to generate a binary flag that identifies exactly when a data entity transitions to a new state.