Question

I'm trying to create a report that essentially redisplays the log tables for better readability, so all changes are captured in two columns, one Original Value and one Current Value column with a attribute column labelling what was changed.

I've created a Temp Table for SQL Server for ease of testing.

declare @T table (Utility_ID int,   
                  Utility_Record_ID int,    
                  Organization_Name nvarchar(255), 
                  Facility_Name nvarchar(255),  
                  Space_Name nvarchar(255), 
                  Utility_Name nvarchar(255),   
                  MeterNumber nvarchar(255),    
                  Data_Type nvarchar(255),  
                  Reading decimal(18,2),    
                  Consumption decimal(18,2),    
                  Begin_Date datetime,  
                  End_Date datetime,    
                  [Estimated/Actual] nvarchar(255), 
                  [Date-Time Of Change] datetime,   
                  [changed By] nvarchar(100),   
                  [Change Type] nVarchar(100)
)

insert into @T 
select 11819,   38503,  'The Men Who Stare At Goats', 'BuildingA', NULL, 'Electricty for BuildingA',    '9615(small meter)',    'Reading',  2369,   9.00,   '2011 -06-30 00:00:00:000', NULL,       'Actual',   '2012-03-07 09:26:53.590',  'Billy.Bob',    'Insert'    
union all
select 11819,   38503,  'The Men Who Stare At Goats', 'BuildingA', NULL, 'Electricty For BuildingA',    '9615(small meter)',    'Reading',  2372,   12.00,  '2011 -06-30 00:00:00:000', NULL,       'Actual',   '2012-05-01 10:30:40:237',  'Billy.Jean',   'Update'    
union all
select 2000,    12345,  'Hotel', 'Fun House', 'My Gaff', 'Water For My Gaff',   '987654321',    'Consumption',  NULL,   500.00, '2011 -06-30 00:00:00:000', '2011 -08-30 00:00:00:000',     'Actual',   '2013-05-01 10:30:40:237',  'Billy.NoMates',    'Insert'

My obstacle is that I'm tracking changes across c.Reading, c.Consumption, estimated/Actual, begin date and end date. How can I implement the other field values to pull through into the CurrentValue and PreviousValue columns if they were changed instead, or, changed with another field?

My attempt below for tracking one column [c.Consumption] I've partitioned by ID and ordered by the recorded date-time of change.

-- 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],
C.Consumption as CurrentValue,
P.Consumption as PreviousValue,
  case C.Consumption when P.Consumption then 0 else 1 end as Changed
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   

This catch is, that I'm using a read only access account, so no triggers or views. This must be select query pure and simple.

Was it helpful?

Solution

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   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top