【问题标题】:How to check if the contents of two columns from different tables are identical?如何检查来自不同表的两列的内容是否相同?
【发布时间】:2019-11-08 15:26:08
【问题描述】:

我的 SQL 数据库中有两个表。我想检查Specifier 列的数据是否完全相同。

OK 情况,因为两个表在Specifier 列中具有相同顺序的相同数据:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     1         
183     2       

错误情况,因为数据不同:

-- Table1:
RowID   Specifier
187     1         
188     2         
189     3         

-- Table2:
RowID   Specifier
181     1         
182     2         
183     2    

错误情况,因为数据的顺序不同:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     2         
183     1   

错误情况,由于数据量不同:

-- Table1:
RowID   Specifier
187     1         
188     1         
189     2         

-- Table2:
RowID   Specifier
181     1         
182     1         
183     2
184     1       

我编写了以下查询,它几乎可以正常工作,并且如果一个表有值而另一个表没有值,它会正确给出错误,但如果只是顺序不正确,它不会错误地给出错误:

IF EXISTS
    (SELECT Specifier FROM Table1 EXCEPT SELECT Specifier FROM Table2
    UNION ALL
    SELECT Specifier FROM Table2 EXCEPT SELECT Specifier FROM Table1)
BEGIN
    THROW 99999, 'Mismatching Specifiers between the two tables', 1;
END;

【问题讨论】:

  • rowid 是否也匹配或者相同的 Specifier 可以有不同的 rowid?
  • 做一个完整的外连接。
  • @JuanCarlosOropeza 不,RowIDs 完全无关
  • rowids 并非无关紧要,它们只是不匹配。如果要强制执行行顺序规则,则需要在 ORDER BY 子句中使用它们。
  • @EricBrandt 啊,好的。

标签: sql sql-server tsql sql-server-2016


【解决方案1】:

您可以使用full joinrow_number()。以下获取异常:

select *
from (select t1.*, row_number() over (order by rowid) as seqnum
      from table1 t1
     ) t1 full join
     (select t2.*, row_number() over (order by rowid) as seqnum
      from table2 t2
     ) t2
     on t1.seqnum = t2.seqnum and t1.specifier = t2.specifier
where t1.seqnum is null or t2.seqnum is null;

如果你只是想要一个标志:

select (case when count(*) > 1 then 1 else 0 end)
from (select t1.*, row_number() over (order by rowid) as seqnum
      from table1 t1
     ) t1 full join
     (select t2.*, row_number() over (order by rowid) as seqnum
      from table2 t2
     ) t2
     on t1.seqnum = t2.seqnum and t1.specifier = t2.specifier
where t1.seqnum is null or t2.seqnum is null;

如果您关心性能,使用exists 的第一个查询应该更快。

【讨论】:

    【解决方案2】:

    似乎使用起来可能更容易

    IF EXISTS (SELECT 1
               FROM (SELECT ROW_NUMBER() OVER (ORDER BY RowID) AS RN,
                            Specifier
                     FROM Table1) T1
                    FULL OUTER JOIN (SELECT ROW_NUMBER() OVER (ORDER BY RowID) AS RN,
                                            Specifier
                                     FROM Table2) T2 ON T1.RN = T2.RN
                                                    AND T1.Specifier = T2.Specifier
               HAVING COUNT(CASE WHEN T1.RN IS NULL OR T2.RN IS NULL THEN 1 END) >= 1) ...
    

    【讨论】:

    • 这似乎也错误地比较了RowID 列。它们在这里完全无关紧要。
    • 如果RowID “完全不相关” 那么你如何定义Specifier、@ruohola 的值的顺序?如果与问题无关,为什么在您的问题中包含RowID
    • 我的意思是根本不应该比较它们。
    • 如您所见,如果只有RowIDs 是:dbfiddle.uk/…,您会说“有些不同”
    • 是的,@ruohola,因为有些东西不同的。 RowID的值。
    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 2020-07-16
    • 1970-01-01
    • 2012-03-29
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    相关资源
    最近更新 更多