• SQLSERVER中如何快速比较两张表的不一样


    一般来说,如何检测两张表的内容是否一致,体现在复制的时候发布端和订阅端的两端的数据上面

    我这里罗列了一些如何从数据库层面来解决此类问题的方法


    第一步当然就是检查记录数是否一致,否则不用想其他方法了~
    这里我们用两张表t1_old,t1_new来演示


    方法介绍

    方法一:老老实实看表结构和表记录数,弊端是根本看不到两张表的数据是否一致,只是看到表结构和记录数是否一致

    --表结构:
     CREATE TABLE t1_old (
      id int NOT NULL,
      log_time DATETIME DEFAULT ''
    ) ;
    CREATE TABLE t1_new ( id int NOT NULL, log_time DATETIME DEFAULT '' ) ; --两表的记录数都为100条。 select count(*) from t1_old; select count(*) from t1_new;

    方法二:加法去重 union 运算符排除重复的,但是有bug,在某些情形下不能简单表示结果集一致,相当于无效

    由于Union 本身具备把上下两条连接的记录做唯一性排序,所以这样检测起来比较简单

    SELECT  COUNT(*)
    FROM    ( SELECT    *
              FROM      [t1_old]
              UNION
              SELECT    *
              FROM      [t1_new]
            ) AS T;
    
    
    INSERT INTO [dbo].[t1_new]
            ( [id],[log_time] )
    VALUES(1,''),(3,''),(4,'')
    
    INSERT INTO [dbo].[t1_old]
            ( [id],[log_time] )
    VALUES(1,''),(2,''),(3,'')
    
    SELECT * FROM [dbo].[t1_new]
    SELECT * FROM [dbo].[t1_old]
    
    SELECT  COUNT(*)
    FROM    ( SELECT    *
              FROM      [t1_new]
              UNION
              SELECT    *
              FROM      [t1_old]
            ) AS T;

    两表数据

    查询出来的结果是4

    方法三:EXCEPT  减法归零

    SELECT  COUNT(*)
    FROM    ( SELECT    *
              FROM      [dbo].[t1_new]
              EXCEPT
              SELECT    *
              FROM      [dbo].[t1_old]
            ) AS T;
    
    SELECT  COUNT(*)
    FROM    ( SELECT    *
              FROM      [dbo].[t1_old]
              EXCEPT
              SELECT    *
              FROM      [dbo].[t1_new]
            ) AS T;
    
    SELECT * FROM [dbo].[t1_new]
    
    SELECT * FROM [dbo].[t1_old]

    这里检测出来结果不对,那么就直接给出不一致的结论

    方法四:用全表INNER JOIN,这个也是最烂的做法,当然这里指的是在表记录数超级多的情况下

    DECLARE @t1_newcount BIGINT
    DECLARE @count BIGINT
    
    
    SELECT  @t1_newcount = COUNT(*)
    FROM    t1_new;
    
    
    SELECT  @count = COUNT(*)
    FROM    [t1_old] AS a
            INNER JOIN [t1_new] AS b ON [b].[id] = [a].[id]
                                        AND [b].[log_time] = [a].[log_time] --如果表中还有其他字段的自行添加
    PRINT @count
    PRINT @t1_newcount
    IF ( @count = @t1_newcount )
        BEGIN 
            SELECT  'equal'
        END 
    ELSE
        BEGIN
            SELECT  'not equal'
    
        END 

    方法五:借助SQLSERVER自带的tablediff工具,当初微软制作这个工具的目的就是用于比较复制中发布表和订阅表的数据一致

    identical是相等的意思

    方法六:借助发布端的验证订阅功能,验证订阅端跟发布端的数据是否一致

    方法七:用checksum校验,比较两张表里的内容的checksum值是否一致

    但是这种方法也只局限于两表结构一摸一样

    我把[t1_new]表的数据复制到一张新的表以便进行比较

    SELECT * FROM [dbo].[t1_new]
    SELECT * FROM [dbo].[t1_newreplica]
    
    
    
    SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_old]
    SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_new]
    SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_newreplica]


    总结

    从上面几种数据库提供的方法来看,用EXCEPT减法来归零相对来说比较可靠,其他的方法比较适合在特定的情形下来检测

    如有不对的地方,欢迎大家拍砖o(∩_∩)o 

    本文版权归作者所有,未经作者同意不得转载。

  • 相关阅读:
    自然常数e怎么得来的?
    一元线性回归模型
    最小二乘法
    Box-Cox转换
    需要的数学技能
    偏导数
    FineReport 表格分类
    FineReport 普通报表
    FineReport 单元格
    FineReport创建普通报表的流程
  • 原文地址:https://www.cnblogs.com/lcword/p/5564937.html
Copyright © 2020-2023  润新知