يمكنك إعادة بناء السجلات. سيكون الاستعلام مرهقًا بعض الشيء. المنطق هو القيام بما يلي لحقل معين ، يتم تقديم القيمة من خلال القواعد التالية:
- القيمة الجديدة للسجل مع الإصدار الأصغر التالي من VersionNumber
- القيمة القديمة للسجل مع الإصدار الأعلى التالي من VersionNumber
- القيمة الحالية
فيما يلي مثال (مع عدد أقل من الحقول):
select t1.objId, t1.userId,
max(case when tv.FieldName = 'Data1' and VersionNumber < @VersionNumber
then tv.NewValue
when tv.FieldName = 'Data1' and VersionNumber > @VersionNumber
then tv.OldValue
when tv.FieldName = 'Data1' and VersionNumber is null
then t.Data1
end) as Data1,
max(case when tv.FieldName = 'Data2' and VersionNumber < @VersionNumber
then tv.NewValue
when tv.FieldName = 'Data2' and VersionNumber > @VersionNumber
then tv.OldValue
when tv.FieldName = 'Data2' and VersionNumber is null
then t.Data2
end) as Data2,
. . .
from table1 t1 left outer join
(select tv.*,
row_number() over (partition by objId, userId, fieldname
order by abs(VersionNumber - @VersionNumber)
) as seqnum
from table_var tv
) tv
on tv.objId = t.objId and tv.userId = t.userId and seqnum = 1
group by t1.objId, t1.userId;
يتمثل أحد التحديات في هذا المنطق إلى التأكد من أن القيمة الحالية لا تخلط بطريق الخطأ في القيم السابقة. ال left outer join
مع seqnum = 1
يعالج هذا. يتم استخدام القيمة الحالية فقط عندما لا يكون هناك تطابق مع القيمة السابقة أو الناجحة.