如何比较两个表之间的每一列

时间:2014-07-15 06:07:17

标签: sql sql-server

我有两个表,T1和T2,每个表有十列:teacher1,teacher2,teacher3,teacher4,teacher5,student1,student2,student3,student4,student5。

如何获得T1和T2符合以下两条规则的行?

在规则中学生*表示student1 student2 ...老师*表示老师1老师2 ...

  
      
  1. T1和T2不同,这意味着T1中的至少一个值不在T2中。
    (尽管列顺序,T1 teacher1可以出现在T2 student *或teacher *列中)
  2.   
  3. T1老师*中至少有一位是T2老师*或者T1学生*中至少有一位是T2学生*,这意味着T1和T2至少有一个普通的老师或学生。
  4.   

例如,如果T1有一行

C2      NULL    NULL    NULL    NULL    S1      NULL    NULL    NULL    NULL

和T2有行

NULL    NULL    NULL    S1      NULL    NULL    C2      NULL    NULL    NULL
S1      NULL    NULL    C3      NULL    C2      NULL    NULL    NULL    NULL
NULL    NULL    NULL    C2      NULL    S2      NULL    S3      NULL    NULL

预期结果只是T2的第三行,因为:

  • 第一行符合rule2但不符合rule1。
  • 第二行符合rule1但不符合rule2。
  • 第三行符合rule1和rule2。

我想使用CharIndex函数,但每个表都有超过一百万行,它的速度非常慢。

2 个答案:

答案 0 :(得分:0)

如果您遇到这种糟糕的设计,那么您没有太多的有用选项,但您可能会发现解决方案是停止尝试在TSQL中执行此操作。您几乎被迫进行全表扫描(除非您没有提及某些where子句子集,但是相同的where子句将继续在避免全表扫描方面起作用。)

对于许多字符串操作,TSQL的性能非常糟糕。用C#或其他一些编译语言编写测试,它们的运行速度比等效的TSQL代码快得多。

您可以编写CLR proc(SqlServer 2005+)或旧式客户端服务器应用程序。在任何一种情况下,您基本上都会吮吸整个表并在编译代码中进行所有必要的比较。将所有数据吸收到客户端将相对较慢,尤其是如果客户端和服务器之间的网络连接速度较慢。

一旦您选择了记录,或者大致选择了多少记录,您就不会说出您打算对记录做什么,但除非您最终选择的行数超过几千行,否则性能问题不应该真正做到您决定CLR与传统客户端服务器。

作为第一个近似,只需编写一个快速而简单的程序,只需读取每条记录,看看处理时间是否可接受。

处理时不要将所有记录保留在内存中。即,一次处理一条记录并执行规则测试并丢弃记录,如果它与您的规则不符。

如果你必须发布大量数据,如果你一次做一个记录,这将是非常慢的。 ---这就是为什么你试图避免基于客户端(或CLR)的大型结果集处理。

另外,我假设您可以将较小的表保留在内存中,并且有一个可行的策略来减少将T1中的每一行与T2中的每一行进行比较的时间

ADDED

我能想到的唯一另一件事就是改变你的设计,至少要创建适当规范化的补充临时表并根据需要构建它们以便在查询中使用。听起来像很多工作而且它不会很快,因为编写这些临时表会有很多I / O和索引,然后你仍然需要在TSQL中执行所有规则,所以更多的I / O,等

答案 1 :(得分:0)

为什么不尝试添加校验和列并将其与驱动程序列匹配?

ALTER TABLE Table_Name
   ADD Checksum_Column_Name AS CHECKSUM(Column1, Column2, Column3,...);
GO 

如果数据相同,校验和将相等。