SQL Update表 - 基于日期的2个表 - 表2表1的子集

时间:2015-08-04 19:45:36

标签: sql sql-server

好的我有一个相当独特的情况,我无法相信没有比我的解决方案更好的方法。 要求:

  1. 表2 - EpmTask_UserView_RM是表1的子集 -
    MSP_EpmTask_UserView因此,当所有字段匹配时,表1中有很多
    比表2更多的行
  2. 表2需要根据任务更改的日期从表1更新(我们无法执行删除和替换)有三种情况:
  3. 任务更新有关任务的更改(我们将根据任务日期戳记知道)
  4. 任务删除任务已删除的位置
  5. 任务添加新任务存在的位置
  6. 我有3个不同的查询,并且我认为有更好的方法。

    **** DELETE Tasks from ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM table if no longer present in Production***/
    
    USE [ProjectWebApp]
    GO
    
            DELETE FROM [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
            WHERE [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TaskUID IN
    
                (SELECT
                /*Subquery to select all records in ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM NOT found in MSP_EpmTask_UserView_RM */
                  [ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].[TaskUID]
                  FROM [ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
                  LEFT JOIN [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView] as Prod
                  on Prod.TaskUID = [ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TASKuid
                  where Prod.TaskUID is NULL)
    

    查询2更新

        UPDATE [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
    
    SET 
         [ProjectUID] = Source.[ProjectUID]
        ,[TaskUID] = Source.[TaskUID]
        ,[TaskName] = Source.[TaskName]
        ,[TaskIndex] = Source.[TaskIndex]
        ,[TaskOutlineLevel] = Source.[TaskOutlineLevel]
        ,[TaskOutlineNumber] = Source.[TaskOutlineNumber]
        ,[TaskStartDate] = Source.[TaskStartDate]
        ,[TaskFinishDate] = Source.[TaskFinishDate]
        ,[TaskActualStartDate] = Source.[TaskActualStartDate]
        ,[TaskActualFinishDate] = Source.[TaskActualFinishDate]
        ,[TaskPercentCompleted] = Source.[TaskPercentCompleted]
        ,[Health] = Source.[Health]
        ,[Milestone Significance Level] = Source.[Milestone Significance Level]
        ,[TaskModifiedDate] = Source.[TaskModifiedDate]
        ,[TaskBaseline1StartDate] = Source.[TaskBaseline1StartDate]
        ,[TaskBaseline1FinishDate] = Source.[TaskBaseline1FinishDate]
        ,[TaskBaseline1Duration] = Source.[TaskBaseline1Duration]
        ,[QueryTimestamp] = GetDate()
    FROM [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView] AS Source
    
    WHERE Source.TaskUID = [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TaskUID
    AND GetDate() - Source.TaskModifiedDate <= .01 -- Update any task changed in last 14 minutes (14 minutes = 1% of a full day, ie '.01')
    
    GO
    

    任务3添加

        SELECT 
           [MSP_EpmProject_UserView].[ProjectUID]
    
          ,[TaskUID]
          ,[TaskName]
          ,[TaskIndex]
          ,[TaskOutlineLevel]
          ,[TaskOutlineNumber]
          ,[TaskStartDate]
          ,[TaskFinishDate]
          ,[TaskActualStartDate]
          ,[TaskActualFinishDate]
          ,[TaskPercentCompleted]
          ,[Health]
          ,[Milestone Significance Level]
          ,[TaskModifiedDate]
          ,[TaskBaseline1StartDate]
          ,[TaskBaseline1FinishDate]
          ,[TaskBaseline1Duration]
        ,GetDate() as QueryTimestamp
    
    
      INTO [ProjectWebApp].[dbo].[MSP_EpmTask_UserView_RM] 
    
      FROM [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView]
      Inner Join [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmProject_UserView]
      on [MSP_EpmProject_UserView].projectUID = [MSP_EpmTask_UserView].ProjectUID
      WHERE [SMO Programs] = 'SMO Day 1 Release Management'
      AND [Milestone Significance Level] is not null
      /*AND [TaskModifiedDate] > (getdate() - 1)*/
    

    思想?

1 个答案:

答案 0 :(得分:0)

这似乎是MERGE语句的理想情况。如果您没有多使用它们,或者根本没有使用它们,我强烈建议this site作为入门。

MERGE可以在适当的条件下一次性执行INSERTUPDATEDELETE。基本思路是比较两个表中的行,源和目标,以及比较(以及可能的其他条件),然后采取适当的操作。

MERGE可以很好地执行,因为它会批量执行这些操作 - 但请测试一下。有时人们发现它们比在某些情况下使用单独的语句要慢。索引正确(Microsoft建议索引用于连接两个表的列)可以帮助很大。正确地编写MERGE语句非常重要,无论是获得正确的结果还是获得良好的性能 - 如果您之前没有使用它们,那么请务必阅读。以上链接是一个很好的启动,但还有很多其他文章。