比较两个集合是否相等(Transact-SQL Cookbook)

 2.4.1问题
你想要比较两个集合的行以确定两个集合是否相等。例如,你有十月和十一月的学生表的镜像。现在,你想要比较这两份拷贝。

十月镜像如下:

CourseId             StudentName    Score  TermPaper   

-- ------------------ -------------- ------ ----------- 

ACCN101              Andrew         
11.00    3

十一月如下:

CourseId             StudentName   Score  TermPaper   

-- ------------------ ------------- ------ ----------- 

ACCN101              Andrew        
11.00    3

ACCN101              Andrew        
11.00    3

ACCN101              Bert          
13.40    1

2.4.2解决方案

一个方案是将两张表作为两个不同的集合。然后你可以采用“实现集合差集”方法解决这个问题,使用这个方法查询在一张表而不在另一张表中的行。下面的查询会对名为StudentsOct和StudentsNov的表采用此方案:

SELECT  so. * COUNT ( * ) DupeCount,  ' StudentsOct '  TableName
FROM  StudentsOct so
GROUP   BY  so.CourseId, so.StudentName, so.Score, so.TermPaper
HAVING   NOT   EXISTS  (
      
SELECT  sn. * COUNT ( * )
      
FROM  StudentsNov sn
      
GROUP   BY  sn.CourseId, sn.StudentName, sn.Score, sn.TermPaper
      
HAVING  sn.CourseId = so.CourseId  AND  
         sn.TermPaper
= so.TermPaper  AND  
         sn.StudentName
= so.StudentName  AND
         
COUNT ( * =   COUNT ( ALL  so.CourseId))
UNION
SELECT  sn. * COUNT ( * ) DupeCount,  ' StudentsNov '  TableName
FROM  StudentsNov sn
GROUP   BY  sn.CourseId, sn.StudentName, sn.Score, sn.TermPaper
HAVING   NOT   EXISTS  (
      
SELECT  so. * COUNT ( * )
      
FROM  StudentsOct so
      
GROUP   BY  so.CourseId, so.StudentName, so.Score, so.TermPaper
      
HAVING  so.CourseId = sn.CourseId  AND  
         so.TermPaper
= sn.TermPaper  AND  
         so.StudentName
= sn.StudentName  AND
         
COUNT ( * =   COUNT ( ALL  sn.CourseId))

2.4.3讨论

这是一个有些复杂的查询。然而,它实际上是两个十分相似的SELECT语句的并集。一旦你理解了第一个,你就会理解第二个。第一个UNION中的SELECT语句返回存在于StudentsOct而不在StudentsNov中的行列表。第二个SELECT语句恰恰相反—返回在StudenstNov中而不在StudentsOct中行列表。这两个SELECT语句代表了不同的操作。如果两个表相等,没有SELECT会返回行。

让我们关注SELECT语句的第一部分:

SELECT  so. * COUNT ( * ) dupeCount,  ' StudentsOct '  tableName
FROM  StudentsOct so
GROUP   BY  so.CourseId, so.StudentName, so.Score, so.TermPaper

这个SELECT语句获取StudentsOct表中的所有列,根据这些列分组,使用聚合函数COUNT返回每一组中和行数。例如:

CourseId     StudentName Score  TermPaper   DupeCount   TableName

-- ---------- ----------- ------ ----------- ----------- -----------

ACCN101      Andrew       
11.00    3             1           StudentsOct

...

使用GROUP BY子句列出StudentOct表中每一列是很重要的。在这个示例中,我们加入了额外的TableName列,所以我们可以很容易地看出行属于哪张表。分组操作的目的是处理重复行。如果StudentsOct表有两个相同的行,那么StudentsNov表就必须有两个相同的行相匹配。解决这个问题的唯一方法根据表中的所有行进行分组,计算每个分组中出现的次数,然后在两张表间比较这些次数。

Having子句和WHERE子句一样,但是在分组级别。对于一个表中的每个分组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值