T-SQL通过RelevanceDate从table / log_table中检索历史数据

时间:2012-03-19 13:18:17

标签: sql sql-server tsql

我有以下表格:

1) TBL (ID, Data, LastUpdated, DateCreated)
2) TBL_LOG(Log_ID, LogCreateDate, ID, Data, LastUpdated, DateCreated)

TBL用于存储当前数据,TBL_LOG用于存储TBL中的每项数据更改(使用更新触发器,已删除的记录从TBL复制到{{ 1}})。

现在我需要按相关日期检索数据 我如何编写将根据TBL_LOG返回数据的表值函数(或其他替代方法)。

我理解逻辑,但我找不到在SQL中编写它的好方法...
逻辑如下:

RelevanceDate

对于@RelevanceDate = '2011-03-01' IF TBL.LastUpdated <= @RelevanceDate THEN return data from TBL ELSE IF Exists data in TBL_LOG where TBL_LOG.LastUpdated <= @RelevanceDate THEN return most resent data from TBL_LOG where TBL_LOG.LastUpdated <= @RelevanceDate ELSE IF Exists data in TBL_LOG where TBL_LOG.LastUpdated > @RelevanceDate THEN return the oldest data from TBL_LOG.LastUpdated > @RelevanceDate ELSE return data from TBL 中的所有记录,此函数应使用上述逻辑返回数据。

简而言之,对于TBL中的每一行,我都需要“RelevanceDate”上的数据。

2 个答案:

答案 0 :(得分:1)

在调查结束时,我最终得到了类似的内容:

DECLARE @RelevanceDate DATETIME
SET @RelevanceDate = '2012-03-01'

SELECT 
        MainData.ID, MainData.Data, MainData.LastUpdated, MainData.DateCreated
FROM   (
           SELECT 
                  *
                  ,ROW_NUMBER() OVER(PARTITION BY AllData.ID, AllData.RowNum ORDER BY AllData.LastUpdated) AS MainRowNumber
           FROM   (
                      --Current Data
                      SELECT 
                             NULL LogID
                            ,NULL LogCreateDate
                            ,*
                            ,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY LastUpdated DESC) AS RowNum
                      FROM   TBL
                      WHERE  (lastupdate<=@RelevanceDate)

                      UNION

                      --History Data
                      SELECT  
                            *
                            ,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY LastUpdated) AS RowNum
                      FROM   TBL_LOG
                      WHERE  lastupdate>@RelevanceDate
                  ) AllData WHERE AllData.RowNum=1
       ) MainData
WHERE  MainData.MainRowNumber = 1

如果有人建议如何以更好的方式完成,我很乐意看到它:)

答案 1 :(得分:0)

你可以在你的选择中使用NESTED CASE语句,大致沿着以下几行:

SELECT
    CASE WHEN TBL.LastUpdated <= @RelevanceDate  THEN TBL.data ELSE
        CASE WHEN TBL_LOG.LastUpdated < @RelevanceDate AND NOT TBL_LOG.Data IS NULL THEN 
             TBL_LOG.Data
        ELSE
             ...
        END
    END AS Data
FROM TBL TBL
LEFT JOIN TBL_LOG TBL_LOG
ON TBL.ID = TBL_LOG.ID