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    name1      a1      a2      b

B表数据如下:id    name1      a3     c

根据需求,B表中有一条记录和A表有重复,因此,在A表中,把该重复记录的一条去掉,结果数据如下:id    name1      a2      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
             )


分别来看一下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 )

第二种实现方式,通过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

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

我们来看下结果

(本文完)

				
时间: 2024-10-09 22:08:44

SQL求差集的相关文章

List&lt;T&gt; 求差集

List<int> a = new List<int>() { 1, 2, 3, 6, 8, 7 }; List<int> b = new List<int>() { 1, 2, 3, 4, 5, 6 }; List<int> c = b.Except(a).ToList(); foreach (int i in c) { Console.WriteLine(i); //4 5 } Console.Read(); List<T> 求差

hive 求差集

hive求差集的方法 1.什么是差集 set1 - set2,即去掉set1中存在于set2中的数据. 2.hive中计算差集的方法,基本是使用左外链接. 直接上代码 select * from table1 t1 left outer join table2 t2 on t1.id = t2.id where t2.id = null; 3.一般来说我们要先去重,使得两个表都变成集合,元素唯一. 先对table2(右表)去重然后再计算差集. select * from ( select * f

Silverlight项目笔记6:Linq求差集、交集&amp;检查网络连接状态&amp;重载构造函数复用窗口

一.使用Linq求差集.交集 使用场景: 需要从数据中心获得用户数据,并以此为标准,同步系统的用户信息,对系统中多余的用户进行删除操作,缺失的用户进行添加操作,对信息更新了的用户进行编辑操作更新. 所以需要通过对数据中心以及系统现有用户信息进行比较,分为三部分: (1) Linq取差集,找出需要删除的用户数据,进行删除(USERNAME为唯一值字段). 使用的是Except这个方法. (2)使用Linq提供的Intersect方法,取得两个用户集合的交集,遍历检查进行更新. (3)同样再次取差集

jquery 数组求差集,并集

var alpha = [1, 2, 3, 4, 5, 6], beta = [4, 5, 6, 7, 8, 9]; $.arrayIntersect = function(a, b){ return $.merge($.grep(a, function(i) { return $.inArray(i, b) == -1; }) , $.grep(b, function(i) { return $.inArray(i, a) == -1; }) );}; window.console &&

python中列表之间求差集、交集、并集

求两个列表的交集.并集.差集 def diff(listA, listB): # 求交集的两种方式 retA = [i for i in listA if i in listB] retB = list(set(listA).intersection(set(listB))) print("retA is :", retA) print("retB is :", retB) # 求并集 retC = list(set(listA).union(set(listB))

SQL求 交集 并集 差集

故事是这样的-.. 故事情节: 表 tb_test 有两列, colA , colB; 求 colA , colB 的并交差集-   -- 计算并集 SELECT DISTINCT colB FROM tb_test UNION SELECT DISTINCT colA FROM tb_test -- 计算交集 SELECT DISTINCT colB FROM tb_test INTERSECT SELECT DISTINCT colA FROM tb_test -- 计算差集 SELECT

sql求两表的并集、交集、非交集、差集、结果集排序

create table A( id int IDENTITY(1,1) Not null primary key, name varchar(20) not null default(''), ) INSERT INTO [A]([name]) VALUES('a') INSERT INTO [A]([name]) VALUES('b') INSERT INTO [A]([name]) VALUES('c') INSERT INTO [A]([name]) VALUES('d') INSERT

sql 求模 实现 贪婪算法

背景: 最近在维护一个项目, 因新功能需求拓展.  有一个字段存储 一个星期中的几天,可能是全部,也有可能只是其中的星期一, 星期三,等. 因为项目中有一个枚举值, 已作好初始化赋值工作, 而且 客户端开发时直接把组合值合并成一个早已存入这个字段到DB. 我在项目别的地方(动态批量生成月报表时,又需要得到这个具体的频率值. 因为每个月有几个星期一,星期三,不是固定的, 需要动态计算.),  所以, 又需要将其还原为 其中具体对应的 星期一,星期三 等. 这里就需要对这个组合值,进行求模操作. 于

DB2数据库用SQL求时间差

一.求天数之差: ( (MIDNIGHT_SECONDS (h.DEAL_DATE) - MIDNIGHT_SECONDS (a.ALLOT_DATE))  / 60*24) 如果需要修改为小时只差,去掉分母的24即可.h.DEAL_DATE结束时间,a.ALLOT_DATE开始时间. 二.SQL计算天数: select days(end_date) - days(start_date) from table;