• If you're using 2012 or later, you can use LAG.

    SELECT ID

    , FLAG

    , LAG(DT, 1) OVER (PARTITION BY ID ORDER BY DT) AS EffectiveDate

    , DT AS TermDate

    FROM ##Test;

    Note that I'm assuming (and that's a dangerous thing to do) that the Flag alternates between 'S' and 'U'. If that assumption can ever be false, then LAG won't work for you, and you'd probably have to use a CTE to get the latest previous record that was not equal to the current status/flag.