我想合并两张表,上次数据A和这次数据B一样的标记为N,A表有B表没有,就插入B表,标记为X,A表没有B表有,就标记为Y
新表就是A的表的X+B表的N和Y,并需要有标记
不知道大神有没有优化的方法,谢谢了为什么我加不了sql代码?!!!

解决方案 »

  1.   

    sql有EXCEPT 和 INTERSECT 两个操作,可以看看
      

  2.   

    我一般都是用动态脚本实现,下面是我用的方法,其中最终返回结果中ColEqual=0 表示该列的值不相等,如果一行中有一个列不相等则返回的RowEqual就是0(不相等)    DECLARE @ModifyContent NVARCHAR(MAX)
        DECLARE @SourceTableName sysname='dbo.spt_values'--,@TableObjectID INT
        DECLARE @TargetTableName sysname='dbo.spt_values'
        DECLARE @KeyCols VARCHAR(1000)='[number]'   ---根据要比较表的来变更,用于能标识唯一一行数据
        DECLARE @SourceCriteria VARCHAR(1000)=' WHERE type=''P'' AND number BETWEEN 1 AND 5'  --用去返回要比较的数据范围
        DECLARE @TargetCriteria VARCHAR(1000)=' WHERE type=''P'' AND number BETWEEN 6 AND 10'
        DECLARE @JoinCriteria VARCHAR(100)='ts.KeyCol+5=tt.KeyCol'
    DECLARE @IgnorCols VARCHAR(1000)=',DeleteFlag,CreateDate,CreateUser,LUpdateDate,LUpdateUser,tstamp,'
        IF OBJECT_ID('tempdb..#ColData') IS NOT NULL DROP TABLE #ColData
    CREATE TABLE #ColData (Ind VARCHAR(10),TableName sysname,KeyCol VARCHAR(100),ColumnName VARCHAR(100),ColumnValue VARCHAR(255))  --  SELECT * FROM master.dbo.spt_values WHERE type='P' AND  number BETWEEN 1 AND 5     DECLARE @ColNames VARCHAR(2000),@ColValues VARCHAR(2000)
        DECLARE @sql NVARCHAR(MAX)
        SELECT @ColNames=ISNULL(@ColNames+',','')+sc.[Name]
                 ,@ColValues=ISNULL(@ColValues+',','')+'RTRIM(CONVERT(VARCHAR(255),'+sc.[Name]+')) AS '+sc.[Name]
        FROM sys.[columns] AS sc  INNER JOIN sys.[columns] AS tc ON tc.name=sc.name
        WHERE sc.[object_id]=OBJECT_ID(@SourceTableName) AND tc.[object_id]=OBJECT_ID(@TargetTableName)
      --  SELECT @ColNames,@ColValues    SET @sql= 'SELECT * FROM (SELECT ''S'' AS Ind,'''+@SourceTableName+''' AS TableName, '+@KeyCols+' AS KeyCol,'+ @ColValues+' FROM '+@SourceTableName+@SourceCriteria+'  ) AS t UNPIVOT(ColumnValue FOR ColumName  IN ('+@ColNames+')) u'
       -- PRINT @sql
        INSERT INTO  #ColData(Ind,TableName,KeyCol,ColumnValue,ColumnName)
        EXEC( @sql)
        SET @sql= 'SELECT * FROM (SELECT ''T'' AS Ind,'''+@TargetTableName+''' AS TableName, '+@KeyCols+' AS KeyCol,'+ @ColValues+' FROM '+@TargetTableName+@TargetCriteria+'  ) AS t UNPIVOT(ColumnValue FOR ColumName  IN ('+@ColNames+')) u'
        INSERT INTO  #ColData(Ind,TableName,KeyCol,ColumnValue,ColumnName)
        EXEC( @sql)   
        SET @sql=N'SELECT ts.TableName+'':''+CONVERT(NVARCHAR(max),ts.KeyCol) AS Source,tt.TableName+'':''+CONVERT(NVARCHAR(max),tt.KeyCol) AS Target'+CHAR(13)
        +N'      ,ts.ColumnName,ts.ColumnValue,tt.ColumnValue ,CASE WHEN ISNULL(ts.ColumnValue,'''')=ISNULL(tt.ColumnValue,'''') THEN 1 ELSE 0 END AS ColEqual'+CHAR(13)
        +N'      ,CASE WHEN SUM(CASE WHEN ISNULL(ts.ColumnValue,'''')=ISNULL(tt.ColumnValue,'''') THEN 1 ELSE 0 END)OVER(PARTITION BY ts.TableName,ts.KeyCol)=0 THEN 1 ELSE 0 END RowEqual'+CHAR(13)
        +N'FROM #ColData AS ts'+CHAR(13)
        +N'INNER JOIN #ColData AS tt ON '+@JoinCriteria+CHAR(13)
        +N' WHERE ts.Ind=''S'' AND tt.Ind=''T'' AND ts.ColumnName=tt.ColumnName'
        PRINT @sql
        EXEC(@sql)
      

  3.   

    细看看你的要求其实并不需要我的脚本,我脚本主要是用户数据库比较数据的不同用于查看和写log
    用MERGE语句要慎重(数据量大挺耗内存的)
    建议你还是分成几条语句
    显示更新不用的值
    插入不存在的记录
    删除多余的记录所以语句逻辑,但合理运用会提高效率