你的位置:首页 > 数据库

[数据库]SQL求差集


数据库环境:SQL SERVER 2008R2

Sql Server有提供求集合差集的函数——EXCEPT。先看看EXCEPT的用法,

{ <query_specification> | ( <query_expression> ) } { EXCEPT }{ <query_specification> | ( <query_expression> ) }

从 EXCEPT 操作数左边的查询中返回右边的查询未返回的所有非重复值。
上面是摘自MSDN对EXCEPT函数的用法介绍。

在这里,我们的要求有点特别,集合B中存在多少条集合A的记录,那么,在集合A中剔除集合B中对应的记录条数。
假如A表有数据如下:
id    name
1     a
1     a
2     b

B表数据如下:
id    name
1     a
3     c

根据需求,B表中有一条记录和A表有重复,因此,在A表中,把该重复记录的一条去掉,
结果数据如下:
id    name
1     a
2     b
需求已经清晰了,现在开始来实现实现的方法是:分别给a表和b表的重复记录编号,
只要在b表中存在和a表编号、id、name一样的记录,即在a表进行过滤。
先准备基础数据
WITH  a     AS ( SELECT  1 AS id ,            'a' AS NAME        UNION ALL        SELECT  1 AS id ,            'a' AS NAME        UNION ALL        SELECT  2 AS id ,            'b' AS NAME        UNION ALL        SELECT  3 AS id ,            'c' AS NAME        UNION ALL        SELECT  3 AS id ,            'c' AS NAME        UNION ALL        SELECT  1 AS id ,            'a' AS NAME        UNION ALL        SELECT  4 AS id ,            'd' AS NAME       ),    b     AS ( SELECT  3 AS id ,            'c' AS NAME        UNION ALL        SELECT  1 AS id ,            'a' AS NAME        UNION ALL        SELECT  2 AS id ,            'b' AS NAME        UNION ALL        SELECT  3 AS id ,            'c' AS NAME        UNION ALL        SELECT  1 AS id ,            'a' AS NAME       )

View Code

分别来看一下a表和b表的数据

a表       b表

第一种方式,用NOT EXISTS来实现

SELECT id ,      NAME  FROM  ( SELECT  id ,            ROW_NUMBER() OVER ( PARTITION BY id, NAME ORDER BY id ) AS nid ,            NAME       FROM   a      ) a  WHERE  NOT EXISTS ( SELECT NULL             FROM  ( SELECT  id ,                      ROW_NUMBER() OVER ( PARTITION BY id,                               NAME ORDER BY id ) AS nid ,                      NAME                 FROM   b                ) b             WHERE b.nid = a.nid                AND b.id = a.id                AND b.NAME = a.NAME )

View Code


第二种实现方式,通过EXCEPT来实现

SELECT id ,      NAME  FROM  ( SELECT  id ,            ROW_NUMBER() OVER ( PARTITION BY id, NAME ORDER BY id ) AS nid ,            NAME       FROM   a       EXCEPT       SELECT  id ,            ROW_NUMBER() OVER ( PARTITION BY id, NAME ORDER BY id ) AS nid ,            NAME       FROM   b      ) a

View Code

方法1和方法2本质上是一样的思路,只不过写法不同而已。

我们来看下结果

(本文完)






去宁夏旅游最佳路线去宁夏旅游最佳时间宁夏旅游线路报价宁夏旅游攻略大全宁夏旅游路线推荐香港2015年公众假期公布 复活节5天连休 2015世界无烟日主题是什么 北京卫视2015春晚节目单 2015年五一去哪玩比较好?五大美景任你选 丹霞山性博物馆几点开门?韶关丹霞山性博物馆游玩多长时间? 2015三亚龙抬头节在哪里举办?海南三亚二月二龙抬头节举办地点? 丹霞山性博物馆要门票吗?韶关丹霞山性博物馆门票优惠吗? 2015三亚龙抬头节有什么活动?海南三亚二月二龙抬头节活动介绍? 2015广东漂流节几号开幕?广东漂流节开幕时间? 林县到霞客古渡有多远?上林霞客古渡景区怎么去? 黄腾峡漂流五一怎么收费?2015年五一去清远黄腾峡漂流多少钱? 上林霞客古渡景色怎么样?霞客古渡什么季节去最好? 巴黎旅游注意事项 去泰国自助游该如何省钱? 境外怎么发短信? 什么叫落地签证、申根签证? AT28HC256E-12SI SL383 Datasheet AT28HC256E-12SI SL383 Datasheet AT28HC256E12SI? Datasheet AT28HC256E12SI? Datasheet AT28HC256E-12SI? Datasheet AT28HC256E-12SI? Datasheet 内蒙古到港澳4日游 内蒙古到港澳4日游 内蒙古到港澳4日游 包头到香港澳门5日游 包头到香港澳门5日游 包头到香港澳门5日游 内蒙古到香港三日旅游 内蒙古到香港三日旅游 内蒙古到香港三日旅游