How to efficiently version records in an SQL database

后端 未结 4 990
伪装坚强ぢ
伪装坚强ぢ 2021-02-10 15:01

In at least one application, I have the need to keep old versions of records in a relational database. When something should be updated, instead a new copy would be added and th

4条回答
  •  日久生厌
    2021-02-10 15:38

    I have worked with tracking versions of records but never with overlapping ranges. However, I have experience selecting records under similar criteria. Here's a query that should do what you want.

    select  *
    from    t1
    where   VersionId = (select top 1 VersionId
                         from   t1 as MostRecentlyValid
                         where  MostRecentlyValid.ValidFrom <= @AsOfDate
                                and (MostRecentlyValid.ValidTo >= @AsOfDate
                                     or MostRecentlyValid.ValidTo is null)
                                and t1.Id = MostRecentlyValid.Id
                         order by MostRecentlyValid.ValidFrom desc)
    

    This assumes that ValidTo can also be null to indicate no end date. If ValidTo can't be null then you can remove the or condition. This also assumes a record is valid through the end of the day of the ValidTo date. If the record becomes old at the beginning of the day of the ValidTo date change >= to just >.

    This worked for the handful and test data I tried it on but I'm fairly certain it'll work for all cases.

    As for as efficiency, I'm not a SQL expert so I really don't know if this is the most efficient solution.

    To join to another table you could do something like this

    select  *
    from    (select *
             from  t1
             where VersionId = (select  top 1 VersionId
                    from  t1 as MostRecentlyValid
                    where MostRecentlyValid.ValidFrom <= '2014/2/11'
                          and (MostRecentlyValid.ValidTo >= '2014/2/1'
                               or MostRecentlyValid.ValidTo is null)
                          and t1.Id = MostRecentlyValid.Id
                          order by MostRecentlyValid.ValidFrom desc ) ) as SelectedRecords
             inner join t2
                on SelectedRecords.Id = t2.Id
    

提交回复
热议问题