sql查找最小缺失值与重用被删除的键(转载)
转载自:http://blog.csdn.net/yanghua_kobe/article/details/6262550
在数据处理时,我们经常会使用一些“自增”的插入方式来处理数据。比如学生学号:B07051001,B07051002....类似的递增关系的数据。
但是,如果中途因为某些原因将其中的一些记录删除掉之后,就会出现断续的记录。这时,我们可能期待将这些中间的缺失值再次利用。以下,就谈谈如何查找最小缺失值。
首先,我们建一个测试表:tb_Test(主键并未设置为自增长):
- create table tb_Test
- (
- id int primary key,
- val char(1) null
- )
插入一些数据:
- insert into tb_Test values(1,'a')
- insert into tb_Test values(2,'b')
- insert into tb_Test values(3,'c')
- insert into tb_Test values(4,'d')
- insert into tb_Test values(5,'e')
- insert into tb_Test values(6,'f')
- insert into tb_Test values(7,'g')
- 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查找最小缺失值与重用被删除的键(转载)的更多相关文章
- mysql - 最小缺失值查询
初始化数据 DROP TABLE IF EXISTS X; CREATE TABLE X( a INT UNSIGNED PRIMARY KEY, b ) NOT NULL )ENGINE=INNOD ...
- 数据库入门之运行原始 SQL 查找
数据库入门之运行原始 SQL 查找 一旦你设置好了数据库连接,就可以使用 DB facade 来进行查找.DB facade 提供每个类型的查找方法:select.update.insert.dele ...
- 含头结点的单链表C++实现(包含创建,查找,插入,追加,删除,反转,排序,合并,打印,清空,销毁等基本操作)
温馨提示:下面代码默认链表数据为字符型,本代码仅供参考,希望能对找到本随笔的人有所帮助! #include<iostream> using namespace std; typedef s ...
- 树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法
package com.tomsnail.data.tree; /** * AVL二叉平衡树 * @author tomsnail * @date 2015年3月30日 下午4:35:50 */ pu ...
- 【编程题目】查找最小的 k 个元素
5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学 ...
- 查找最小的k 个元素之C#算法实现
紧接着上一篇微软编程面试100题,这次想解决的是查找最小的K个元素,题目是:输入n 个整数,输出其中最小的k 个.例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 ...
- 查找最小的K个元素,使用最大堆。
查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ...
- sql server删除主键约束所想到的
从网上找到了下面一段代码: declare @Pk varchar(100);select @Pk=Name from sysobjects where Parent_Obj=OBJECT_ID('表 ...
- SQL Server 如何添加删除外键、主键,以及更新自增属性
1.添加删除主键和外键 例如: -----删除主键约束DECLARE @NAME SYSNAMEDECLARE @TB_NAME SYSNAMESET @TB_NAME = 'Date'SELECT ...
随机推荐
- 打印W图案
一:规律 二维图形的展示都可以使用二维数组来解决,W图形x轴0,1,2,1,0,1,2.....在0到2直接来回的徘徊 y轴是在一直递增........ 二:代码 @Test /** * 测试打印w图 ...
- [转]网站优化-IIS7下静态文件的优化
本文转自:http://www.cnblogs.com/Leung/archive/2009/10/26/1590256.html 在网站开发过程中,通常我们会对网站的静态文件做处事,像图片文件,CS ...
- RTC之初始化
RTC为了避免初始化一般有3中方法: 一给MCU的VBAT供电,利用MCU的后备寄存器保存已经设置过时间的标志值,RTC初始化时先查询寄存器值如果是已经设置过则不用初始化设置时间 二 当不给VBUAT ...
- sublime text修改TAB缩进为空格
在sublime text中将TAB缩进直接转化为4个空格,可以按照如下方式操作: 菜单栏: Preferences -> Settings – More -> Syntax Specif ...
- live(),bind(),delegate()等事件绑定方法的区别及应用解析
1 首先bind()方法是最直观的,但是也是弊端最大的. $('a').bind('click',function(){alert('that tickles!')}) 这和事件冒泡有直接关系,当我们 ...
- ActiveMQ(5.10.0) - Configuring the Simple Authentication Plug-in
The easiest way to secure the broker is through the use of authentication credentials placed directl ...
- django 学习-2 模板
如何使用渲染模板的方法来显示内容. 1.创建一个项目dream django-admin.py startproject dream cd dream 再创建一个应用 python m ...
- Android Studio 快捷方式
Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ctrl+Shift+N 查找文件 Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如g ...
- 删除mssqlserver表数据,使id从0开始
********************************* 注意备份好数据! *************************** 1.删除表数据 delete 表名 2.执行 dbcc c ...
- WinForm 实现登录,验证成功,关闭登录界面,显示主界面
点击登录按钮时: ") { this.DialogResult = DialogResult.OK; this.Close(); } else { MessageBox.Show(" ...