Its not pretty, but assuming the columns you're monitoring are fixed, then you could hard-code the checks using case statements. This also assumes that only 1 of the tracked fields can change between 2 versions of the record..
-- Get CurrentValue and PreviousValue with a Changed column
;with cte as
(
select *,
row_number() over(partition by Utility_Record_ID order by [Date-Time Of Change]) as rn
from @T
)
select
C.Utility_ID ,
C.Utility_Record_ID,
C.Organization_Name,
C.Facility_Name,
C.Space_Name,
C.Utility_Name,
C.MeterNumber,
C.Data_Type,
C.Reading,
C.Consumption,
C.Begin_Date,
C.End_Date,
C.[Estimated/Actual],
C.[Date-Time Of Change],
C.[changed By],
C.[Change Type],
case
when C.Reading <> P.Reading then 'Reading'
when C.Consumption <> P.Consumption then 'Consumption'
when C.[Estimated/Actual] <> P.[Estimated/Actual] then '[Estimated/Actual]'
when C.Begin_Date <> P.Begin_Date then 'Begin_Date'
when C.End_Date <> P.End_Date then 'End_Date'
end WhatChanged,
case
when C.Reading <> P.Reading then C.Reading
when C.Consumption <> P.Consumption then C.Consumption
when C.[Estimated/Actual] <> P.[Estimated/Actual] then C.[Estimated/Actual]
when C.Begin_Date <> P.Begin_Date then C.Begin_Date
when C.End_Date <> P.End_Date then C.End_Date
end CurrentValue,
case
when C.Reading <> P.Reading then P.Reading
when C.Consumption <> P.Consumption then P.Consumption
when C.[Estimated/Actual] <> P.[Estimated/Actual] then P.[Estimated/Actual]
when C.Begin_Date <> P.Begin_Date then P.Begin_Date
when C.End_Date <> P.End_Date then P.End_Date
end PreviousValue
from cte as C
LEFT OUTER JOIN cte as P
on C.Utility_Record_ID = P.Utility_Record_ID and
C.rn = P.rn + 1