레코드를 재구성 할 수 있습니다. 쿼리는 약간 번거 롭습니다. 논리는 주어진 필드에 대해 다음을 수행하는 것입니다. 값은 다음 규칙에 따라 제공됩니다.
- @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
이것을 처리합니다. 현재 값은 이전 또는 후속 값과 일치하지 않을 때만 사용됩니다.