转载自:http://blog.csdn.net/yanghua_kobe/article/details/6262550

在数据处理时,我们经常会使用一些“自增”的插入方式来处理数据。比如学生学号:B07051001,B07051002....类似的递增关系的数据。

但是,如果中途因为某些原因将其中的一些记录删除掉之后,就会出现断续的记录。这时,我们可能期待将这些中间的缺失值再次利用。以下,就谈谈如何查找最小缺失值。

首先,我们建一个测试表:tb_Test(主键并未设置为自增长):

  1. create table tb_Test
  2. (
  3. id int primary key,
  4. val char(1) null
  5. )

插入一些数据:

  1. insert into tb_Test values(1,'a')
  2. insert into tb_Test values(2,'b')
  3. insert into tb_Test values(3,'c')
  4. insert into tb_Test values(4,'d')
  5. insert into tb_Test values(5,'e')
  6. insert into tb_Test values(6,'f')
  7. insert into tb_Test values(7,'g')
  8. insert into tb_Test values(8,'h')

删除某些记录,制造“断层”:

delete from tb_Test where id in (1,2,4,5,7);

此时表中数据为不连贯的:

此时能看出最小缺失值应该为:1

我们通过下面这段sql能够得到结果:

select 
   case 
      when not exists(select 1 from tb_Test where id=1)

then 1
      else (
         select min(a.id+1) 
           from tb_Test as a
        where not exists 
        (
          select 1 
            from tb_Test as b
         where b.id=a.id+1
        )
     ) 
  end as '最小缺失值';

这里使用了一个小的技巧,原理是将表中所有记录的id加1,再与源表中所有记录的id匹配。这样只要有源表中有id缺失,id+1在源表中就会有匹配不到的值。

比如源表中id序列为:1、2、3、5、7(a.id与b.id),则源表中的id+1序列为: 2、3、4、6、8(a.id+1);

这样再代入子查询中,就可以看到a.id+1=4,和a.id+1=6和a.id+1=8在b.id中不存在匹配值。然后再去最小值:min()这样结果就为4。

但是以上上图中的这个序列3,6,8用子查询得出的结果也应该为4,而正确答案为1,显然只是用子查询这样的方式处理是不完整的。

那为什么要把1单独判断呢?这是由1的位置的特殊性决定的。因为1开始时总是处在序列的最前端的位置(正常情况下)。它的前面已经没有数字了,也就是说不存在a.id+1=1(因为我们默认序列是从1开始增长的)。因此没有哪个数字存在与否能判断出1是否存在。所以1需要单独考虑。

处于同样的原理,我们可以用这种方式重用被删除的键:

只要在前面加上:insert into ti_Test(id,val) Select .....(同上)即可。

当然你可以使用coalesce函数来合并,存在1和不存在1的情况:

如下:

select Coalesce(Min(a.id+1),1)

from tb_Test a

where not exists (
 select 1 
   from tb_Test as b
where b.id=a.id+1
) And exists(select 1 from tb_Test where id=1)

注:coalesce函数用于返回第一个非空值。也就是说如果序列中没有1,在被where筛选器筛选后,返回的值为null,此时min(a.id+1)也为null,这样返回的结果就为1。

最后,并不推荐重用返回值并且在多线程运行时也可能得到重复的键。

sql查找最小缺失值与重用被删除的键(转载)的更多相关文章

  1. mysql - 最小缺失值查询

    初始化数据 DROP TABLE IF EXISTS X; CREATE TABLE X( a INT UNSIGNED PRIMARY KEY, b ) NOT NULL )ENGINE=INNOD ...

  2. 数据库入门之运行原始 SQL 查找

    数据库入门之运行原始 SQL 查找 一旦你设置好了数据库连接,就可以使用 DB facade 来进行查找.DB facade 提供每个类型的查找方法:select.update.insert.dele ...

  3. 含头结点的单链表C++实现(包含创建,查找,插入,追加,删除,反转,排序,合并,打印,清空,销毁等基本操作)

    温馨提示:下面代码默认链表数据为字符型,本代码仅供参考,希望能对找到本随笔的人有所帮助! #include<iostream> using namespace std; typedef s ...

  4. 树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法

    package com.tomsnail.data.tree; /** * AVL二叉平衡树 * @author tomsnail * @date 2015年3月30日 下午4:35:50 */ pu ...

  5. 【编程题目】查找最小的 k 个元素

    5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学 ...

  6. 查找最小的k 个元素之C#算法实现

    紧接着上一篇微软编程面试100题,这次想解决的是查找最小的K个元素,题目是:输入n 个整数,输出其中最小的k 个.例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 ...

  7. 查找最小的K个元素,使用最大堆。

    查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ...

  8. sql server删除主键约束所想到的

    从网上找到了下面一段代码: declare @Pk varchar(100);select @Pk=Name from sysobjects where Parent_Obj=OBJECT_ID('表 ...

  9. SQL Server 如何添加删除外键、主键,以及更新自增属性

    1.添加删除主键和外键 例如: -----删除主键约束DECLARE @NAME SYSNAMEDECLARE @TB_NAME SYSNAMESET @TB_NAME = 'Date'SELECT ...

随机推荐

  1. python(3)-函数动态参数

    先来看一段代码 def show(*arg): print(arg, type(arg)) if __name__ == "__main__": show(1) show(1,2, ...

  2. Hive中自定义函数

    Hive的自定义的函数的步骤: 1°.自定义UDF extends org.apache.hadoop.hive.ql.exec.UDF 2°.需要实现evaluate函数,evaluate函数支持重 ...

  3. 关于JDK中的总结和基本知识总结

    人机交互的图形化界面(GUI) 命令行方式(CLI  command line interface) JDK有不同的版本(linux,mac os, windows) Java 的跨平台性. 软件放到 ...

  4. poj 1848 树形dp

    思路:表示我很弱,这个想不出dp方程,参考网上代码 #include<iostream> #include<algorithm> #include<cstring> ...

  5. hdu 4280 网络流

    裸的网络流,递归的dinic会爆栈,在第一行加一句就行了 #pragma comment(linker, "/STACK:1024000000,1024000000") #incl ...

  6. 编程计算int类型整数的最大值和最小值

    方法一:将一个int类型整数不断加1,加到最大值,再加1,就变成负值(最小值) 最大值就是除最高位外,其余位都为1,-1即是所有位全部是1,右移1位后最高位变0   最小值即是最高位为1,其余位为0, ...

  7. 使用C#动态生成Word文档/Excel文档的程序测试通过后,部署到IIS服务器上,不能正常使用的问题解决方案

    使用C#动态生成Word文档/Excel文档的程序功能调试.测试通过后,部署到服务器上,不能正常使用的问题解决方案: 原因: 可能asp.net程序或iis访问excel组件时权限不够(Ps:Syst ...

  8. Networking - IPv4 报文格式

    每个 IP 数据报都以一个 IP 报头开始.源计算机的 TCP/IP 软件构造这个 IP 报头,目的计算机的 TCP/IP 软件利用 IP 报头中封装的信息处理数据.IP 报头包含大量信息,包括源 I ...

  9. Ajax-数据格式-html

  10. 删除织梦所有待审核稿件sql语句

    先提醒一下 archives是dedecms主表addonarticle 新闻信息表 在dede后台"系统->SQL命令行工具"运行下以命令即可(注意,运行后未审核的数据全被 ...