【问题标题】:SQL: How to best query a history table to create a snapshot overview of a specific dateSQL:如何最好地查询历史表以创建特定日期的快照概览
【发布时间】:2018-03-25 12:16:06
【问题描述】:

我对 SQL 和数据库结构相对较新,并且有一个问题是最好的方法是什么。

我有对象的历史变化数据,有时需要将其转换为特定日期的快照。

数据示例:

ID        Value        UpdateDate

1         4            2017-01-01
2         4            2017-01-03
3         4            2017-01-03
1         7            2017-01-04
2         5            2017-01-08
3         5            2017-01-10
2         8            2017-01-11

我希望能够在任何给定日期创建所有对象的完整概览的快照。例如:

   Current Date: 2017-01-01             |      Current Date: 2017-01-04
ID        Value        LastUpdateDate   |   ID        Value        LastUpdateDate            
                                        |
1         4            2017-01-01       |   1         7            2017-01-04
                                        |   2         4            2017-01-03
                                        |   3         4            2017-01-03
__________________________________________________________________________________
                                        |
   Current Date: 2017-01-08             |      Current Date: 2017-01-12
ID        Value        LastUpdateDate   |   ID        Value        LastUpdateDate            
                                        |
1         7            2017-01-04       |   1         7            2017-01-04
2         5            2017-01-08       |   1         8            2017-01-10
3         4            2017-01-03       |   1         5            2017-01-11

我创建了以下 SQL 查询来创建这些表。但我想知道这是否是最“有效”的方法?实际上我的表非常大,有时每个对象类型有 200K-300K 唯一对象,每天有几千次更新(不是每个对象,但每天只有几千行添加到历史表中,所以它的大小正在增长快)。

SQL 查询:

SELECT * INTO @CurrentOverviewTableName 
FROM @HistoryTableName 
INNER JOIN (
    SELECT ID AS ID_T, MAX(LastUpdateDate) AS LastUpdateDate 
    FROM @HistoryTableName
    WHERE LastUpdateDate  <= @OverviewDate
    GROUP BY ID
) ts 
ON S@HistoryTableName.ID = ts.ID_T AND @HistoryTableName.LastUpdateDate = ts.LastUpdateDate_T;

之后我得到这个例如:

ID        Value        LastUpdateDate        ID_T        LastUpdateDate_T

1         4            2017-01-01            1           2017-01-01
2         4            2017-01-03            2           2017-01-03
3         4            2017-01-03            3           2017-01-03

我删除了最后两列,因为它们是重复的,以获得我需要的内容。同样,这可行,但我想知道这是否是最好的方法?

我正在使用 Azure SQL DB。

【问题讨论】:

    标签: sql azure tsql audit audit-tables


    【解决方案1】:

    你的方法很好。我会使用窗口函数:

    SELECT *
    INTO @CurrentOverviewTableName 
    FROM (SELECT ht.*,
                 MAX(LastUpdateDate) OVER (PARTITION BY id) AS max_LastUpdateDate
          FROM @HistoryTableName ht
         ) ht
    WHERE max_LastUpdateDate = LastUpdateDate;
    

    如果您不想删除该列,请列出您想要的列,而不是使用SELECT *。如果您也不想这样做,请将条件移至 WHERE 子句:

    SELECT ht.*
    INTO @CurrentOverviewTableName 
    FROM @HistoryTableName ht
    WHERE ht.LastUpdateDate = (SELECT MAX(h2.LastUpdateDate)
                               FROM @CurrentOverviewTableName ht2
                               WHERE ht2.id = ht.id
                              );
    

    【讨论】:

      【解决方案2】:

      假设他们不返回 Value,您可以使用下面的代码。如果您希望它们在值中回归的选项,那么您需要一个标识列,最好作为表的主键,并且您将取而代之的是最大标识。子查询会略有变化。主键还可以使子查询更容易返回,只使用主键而不是两个值,ID 和值。见下文。

      --change the date for a different time period
      DECLARE @updateDate date = '2017-01-12'
      DECLARE @temp TABLE (ID int, Value int, updateDate date)
      
      INSERT INTO @temp VALUES 
       (1, 4, '2017-01-01')
      ,(2, 4, '2017-01-03')
      ,(3, 4, '2017-01-03')
      ,(1, 7, '2017-01-04')
      ,(2, 5, '2017-01-08')
      ,(3, 5, '2017-01-10')
      ,(2, 8, '2017-01-11')
      
      SELECT dT.*
            ,(SELECT T2.updateDate 
              FROM @temp T2 
              WHERE T2.ID = dT.Id AND T2.Value = dT.MaxValue) [LastUpdateDate] 
        FROM (
              SELECT ID, MAX(Value) MaxValue 
                FROM @temp T
               WHERE T.updateDate <= @updateDate
               GROUP By ID
             ) AS dT
      

      【讨论】:

        猜你喜欢
        • 2013-01-14
        • 1970-01-01
        • 1970-01-01
        • 2014-11-22
        • 1970-01-01
        • 2020-10-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-17
        相关资源
        最近更新 更多