转载自: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. linux 主机免验证登录

    1.ssh-keygen -t [rsa|dsa],将会生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub 2.scp -p port  ~/.ssh/id ...

  2. hdu 4642 博弈

    思路:不管是Alice,还是Bob,每次操作都会影响最右下角的数,那么如果是1,Alice赢,否则Bob赢 #include<iostream> #include<cstdio> ...

  3. 网页播放amr格式文件

    mp3格式大家都知道,amr格式就陌生了,至少我没听过.百度一下,先给自己扫盲: AMR(Adaptive Multi-Rate):nokia为WB-AMR格式(AWB)的铃声所作的商业命名,以被3G ...

  4. 如何识别Baiduspider

    上周百度站长平台接到某站长求助,表示误封禁了Baiduspider的IP,询问是否有办法获得Baiduspider的所有IP,打算放入白名单加以保护,防止再次误封.在此要告诉各位站长,Baiduspi ...

  5. MyBatis(3.2.3) - ResultMaps: Extending ResultMaps

    ResultMaps are used to map the SQL SELECT statement's results to JavaBeans properties. We can define ...

  6. NPOI读取Excel表格类

    public class NPOIHelper    {        private HSSFWorkbook workbook;        public static IWorkbook Lo ...

  7. Office升级到2013版后无法登录微软账号问题

    自打office从2010版升级到2013版,就再也无法登录微软账号了.每次点击登录,弹出来的框就显示:this feature has been disabled by your administr ...

  8. asp.net连接oracle的问题及方法总结

    .net连oracle数据库的两个方法介绍1. 安装oracle客户端,连接oracle 需要在客户端%oracle_client_home%network/admin/配置tnsnames.ora, ...

  9. C#程序员整理的Unity 3D笔记(十五):Unity 3D UI控件至尊–NGUI

    目前,UGUI问世不过半年(其随着Unity 4.6发布问世),而市面上商用的产品,UI控件的至尊为NGUI:影响力和广度(可搜索公司招聘Unity 3D,常常能看到对NGUI关键词). NGUI虽然 ...

  10. 自定义DZLMoneyLabel

    一.简介 由于父亲生病,好久没有更新博客了,今天10.1 国庆(应该说是昨天了,已经过了12点了),心血来潮自定义了一个小label.这个控件的难度并不大,也没有什么可以值得炫耀的技术点.写这个控件的 ...