根据上一行填充本行的空白栏位,SQL处理方式
我在4年多前,写了一篇Excel处理空白Cell的文章,http://www.cnblogs.com/studyzy/archive/2010/04/07/1706203.html,其实在数据库中也会遇到这种情况。对于普通的OLTP系统来说,应该不会出现,主要是在做OLAP,导入外部数据源时,可能导入系统的就是带有空白记录的数据。
为了方便说明,我举了一个简单的例子,假设一个学生成绩表,有字段“学生ID”和“成绩”,学生ID是主键,自增,成绩只有NULL和1,2,3,4,5这几个值。在录入学生成绩的时候,如果成绩为NULL,就表示该学生成绩和上一个学生的成绩相同。现在要查询某个学生ID的成绩,该怎么查呢?或者要将成绩字段改为不允许为空,怎么把所有NULL的行填上成绩呢?
首先我们先建立示例表:
1 create table t1
2 (
3 ID int identity primary key,
4 Score int null
5 );
6 insert t1
7 values(3),(4),(null),(3),(null),(null),(5);
8
9 select *
from t1

从结果我们可以看到如果要查询学生6的成绩,那么应该先去查学生5的成绩,由于学生5也是空,所以要继续查前一个学生4的成绩,得到分数3,所以学生6的成绩是3.这显然是一个递归问题,如果一直是空,会继续递归下去,直到找到一个成绩为止。要在SQL中使用递归,那么第一个应该想到的就是公用表表达式CTE。关于CTE的语法和说明可以看MSDN:https://msdn.microsoft.com/zh-cn/library/ms186243.aspx
那么我们这里递归的终点是什么呢?是不为空的成绩,递归的链接条件是上一个学生ID=当前学生ID-1.于是我们可以将此次的公用表表达式写为:
1 with t
2 as
3 (
4 select * from t1 where Score is not null
5 union all
6 select t1.ID,t.Score
7 from t
8 inner join t1
9 on t.ID+1=t1.ID
where t1.Score is null
)
select *
from t
order by ID;
得到的结果为:

这里的情况比较特殊ID是连续的,那么如果ID不连续会怎么样呢?我们试着删除ID=5
delete from t1 where ID=
1 with t1new
2 as
3 (
4 select *,ROW_NUMBER() over(order by ID) as RowNo
5 from t1
6 )
7 , t
8 as
9 (
select Id,Score,RowNo from t1new where Score is not null
union all
select t1new.ID,t.Score,t1new.RowNo
from t
inner join t1new
on t.RowNo+1=t1new.RowNo
where t1new.Score is null
)
select *
from t
order by ID

公用表表达式真的很强大,另外在使用View出Report的时候,也可以用CTE,因为在View中不能用临时表,所以使用CTE代替临时表是个不错的解决方案。
根据上一行填充本行的空白栏位,SQL处理方式的更多相关文章
- printf回到上一行开头以及回到本行开头的方法
回到上一行开头 #include <stdio.h> #include <unistd.h> int main(void) { ; ){ printf("%d\n&q ...
- sql 循环处理表数据中当前行和上一行中某值相+/-
曾经,sql中循环处理当前行数据和上一行数据浪费了我不少时间,学会后才发现如此容易,其实学问就是如此,难者不会,会者不难. 以下事例,使用游标循环表#temptable中数据,然后让当前行和上一行中的 ...
- 17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。 (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和。) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行.请采用循环控制语句来实现. (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和.) 1 1 1 1 ...
- SqlServer 游标逐行更新数据,根据上一行的数据来更新当前行
工作中用到的记录一下,游标的详细定义及说明请百度 --游标格式化数据 DECLARE cursor_jxsmb CURSOR FOR --定义一个游标 SELECT F0 FROM dbo.JXSMB ...
- easyui获取选中行上一行的数据
text: 'XX', iconCls: 'icon-ok', handler: function () { var rowI ...
- jqgrid 选中行触发编辑,切换下一行时验证和异步保存上一行数据
有时,我们需要批量修改或填写一些相似的数据.可以以jqgrid表来显示,可能的效果如下: 选中触发行编辑参考:jqgrid 单击行启用行编辑,切换行保存原编辑行 本文主要说说验证和异步保存上一条数据的 ...
- 在linux上一行代码不用写实现自动采集+hadoop分词
在linux上一行代码不用写实现自动采集+hadoop分词 将下面的shell脚本保存成到xxx.sh,然后执行即可 cd /opt/hadoop mkdir spider wget -O spide ...
- 「SAP技术」SAP HU上面的'Obj.to Which HU Belongs'栏位初探
SAP HU上面的'Obj.to Which HU Belongs'栏位初探 HU02,创建一个新的HU, 保存之, HU03显示这个HU 189141203942, 其'obj.to Which H ...
- MATLAB:一个K×M的矩阵,第一列是1,其它都是0,从最后一行开始,每循环一次,最后一行的1往右边移一位,移动到末尾后溢出,重新回到最左边,同时上一行的1往右边移一位
问题:一个K×M的矩阵,第一列是1,其它都是0,从最后一行开始,每循环一次,最后一行的1往右边移一位,移动到末尾后溢出,重新回到最左边,同时上一行的1往右边移一位.上一行溢出时,上上一行的1移动一位, ...
随机推荐
- 解决SqlPlus前台程序出现中文乱码的问题
在使用sqlplus的过程中,常常会遇到某一台机器在访问oracle数据库时中文显示乱码的问题,实际上这是因为客户端字符集和服务器字符集不一致导致的.在实际使用中,服务器字符集,客户端字符集和操作系统 ...
- Verilog学习笔记简单功能实现(六)...............计数分频电路
在分频器电路中最重要的概念有两个:1)奇分频/偶分频:2)占空比. A)其中最简单的就是二分频电路,占空比为50%,其Verilog程序为 module half_clk(clr,clk_in,clk ...
- java.lang.IllegalStateException: Recursive entry to executePendingTransactions
[解决办法]: 将getFragmentManager改为getChildFragmentManager即可
- 【FFmpeg】Windows下64位ffmpeg编译
本文主要记录在64位Windows 7下,编译64位ffmpeg的过程. 1.资源准备 (1). MSYS http://sourceforge.net/projects/mingwbuilds/fi ...
- windows / linux系统中,端口被占用解决方法
一.在windows操作系统中,查询端口占用和清除端口占用的程序 提升权限后用:netstat -b或用 1.查询端口占用的进程ID 点击"开始"-->"运行&qu ...
- .net字符串数组查找方式效率比较
下面是代码: static void Main(string[] args) { string[] arr = new string[] { "AAA", "BBBB&q ...
- 如何在window Form中使用Font Awesome?
随着技术的发展,web上以前的图片按钮现在逐步换成了图标字体,这些图标字体是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真,真心给人一种“高大上”的感觉 ...
- 灵感来自 Google & YouTube 的苗条的进度栏效果
NProgress.js 是纳米级的进度条插件.拥有逼真的的涓涓细流动画效果来告诉你的用户,某些事情正在发生.它的灵感来自于谷歌,YouTube,应用了,这款苗条的进度条是完美的,适用于 Turbol ...
- XSS攻击的解决方法
在我上一篇<前端安全之XSS攻击>文中,并没有把XSS攻击的解决办法说完整,而XSS的攻击又那么五花八门,有没有一招“独孤九剑”能够抗衡,毕竟那么多情况场景,开发人员无法一一照顾过来,而今 ...
- HTML5夜空烟花绽放动画效果
模板描述:HTML5夜空烟花绽放动画效果基于HTML5 canvas制作,模拟夜空烟花绽放动画效果,烟花会在夜空打出贺词,有新年快乐.合家幸福.万事如意.心想事成.财源广进等,文字可以自定义,做成各种 ...