转自 : http://blog.csdn.net/nux_123/article/details/45037719

问题:在项目中有一张设备检测信息表DEVICE_INFO_TBL, 每个设备每天都会产生一条检测信息,现在需要从该表中检索出每个设备的最新检测信息。也就是device_id字段不能重复,消除device_id字段重复的记录,而且device_id对应的检测信息test_result是最新的。

解决思路:用Oracle的row_number() over函数来解决该问题。

开窗函数          
     Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。

开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
1:over后的写法:    
   over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
   over(partition by deptno)按照部门分区

   over(partition by deptno order by salary)

2:开窗的窗口范围:
over(order by salary range between 5 preceding and 5 following):窗口范围为当前行数据幅度减5加5后的范围内的。

举例:

--sum(s)over(order by s range between 2 preceding and 2 following) 表示加2或2的范围内的求和

select name,class,s, sum(s)over(order by s range between 2 preceding and 2 following) mm from t2
adf        3        45        45  --45加2减2即43到47,但是s在这个范围内只有45
asdf       3        55        55
cfe        2        74        74
3dd        3        78        158 --78在76到80范围内有78,80,求和得158
fda        1        80        158
gds        2        92        92
ffd        1        95        190
dss        1        95        190
ddd        3        99        198

gf         3        99        198

over(order by salary rows between 5 preceding and 5 following):窗口范围为当前行前后各移动5行。

举例:

--sum(s)over(order by s rows between 2 preceding and 2 following)表示在上下两行之间的范围内
select name,class,s, sum(s)over(order by s rows between 2 preceding and 2 following) mm from t2
adf        3        45        174  (45+55+74=174)
asdf       3        55        252   (45+55+74+78=252)
cfe        2        74        332    (74+55+45+78+80=332)
3dd        3        78        379    (78+74+55+80+92=379)
fda        1        80        419
gds        2        92        440
ffd        1        95        461
dss        1        95        480
ddd        3        99        388
gf         3        99        293
over(order by salary range between unbounded preceding and unbounded following)或者

over(order by salary rows between unbounded preceding and unbounded following):窗口不做限制

解决过程:

1.查看表中的重复记录

select
    t.id,
    t.device_id,
    t.update_dtm,
    t.test_result
from DEVICE_INFO_TBL t
 
2.标记重复的记录
select
    t.id,
    t.device_id,
    t.update_dtm,
    t.test_result,
    row_number() OVER(PARTITION BY device_id ORDER BY t.update_dtm desc) as row_flg   
from DEVICE_INFO_TBL t
 
3.过滤重复数据,取得最新的记录
select
    temp.id,
    temp.device_id,
    temp.update_dtm,
    temp.test_result
from (

         select
             t.id,
             t.device_id,
             t.update_dtm,
             t.test_result,
             row_number() OVER(PARTITION BY device_id ORDER BY t.update_dtm desc) as row_flg   
          from DEVICE_INFO_TBL t ) temp
where temp.row_flg  = '1'

row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的).

  与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序,而此函数在包含排序从句后是先排序再计算行号码.

  row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序).

  rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内).

  dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的 .

  lag(arg1,arg2,arg3):
arg1是从其他行返回的表达式
arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。
arg3是在arg2表示的数目超出了分组的范围时返回的值。

Oracle去除重复(某一列的值重复),取最新(日期字段最新)的一条数据的更多相关文章

  1. Oracle sql 查询结果某一列字段合并成为一条数据

    使用oracle中自带函数  wmsys.wm_concat(需合并列的字段名) 用法如下: select code,name,wmsys.wm_concat(baname) from tab gro ...

  2. oracle 向数据库同时插入多条数据

    oracle 与 mysql 不同. mysql 可以直接插入多条数据的操作:  采用 INSERT INTO 某表 VALUES(各个值),VALUES(各个值),.....; 或者 INSERT ...

  3. 收集计算机分区信息,去除列中的重复值(Excel)(空行)

    收集计算机分区信息 $servers = gc D:\serverlist.txt $result = $results = $null $results = @() foreach ($server ...

  4. oracle 相关查询和非相关查询,oracle 去除重复数据,以及oracle的分页查询!

    一.oracle中的相关查询?和非相关查询? 二.oracle去除重复数据 1. 2. 3.oracle 实现分页? 利用rownum的唯一性,和子查询,将rownum从伪列变成实际列!

  5. mysql 去除重复 Select中DISTINCT关键字的用法(查询两列,只去掉重复的一列)

    在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...

  6. Oracle-一张表中增加计算某列值重复的次数列,并且把表中其他列也显示出来,或者在显示过程中做一些过滤

    总结: 1.计算某列值(数值or字符串)重复的次数 select 列1,count( 列1 or *) count1  from table1 group by 列1 输出的表为:第一列是保留唯一值的 ...

  7. Oracle 将不同列的值拼接成一个 字符串

    利用拼接操作符“||”或者 CONCAT('','')函数,将不同列的值 拼接成一个 字符串   -- 方法一:推荐 SELECT S.TEAM ||'**'|| S.NAME ||'**'|| S. ...

  8. Oracle复合B*tree索引branch block内是否包含非先导列键值?

    好久不碰数据库底层细节的东西,前几天,一个小家伙跑来找我,非要说复合b*tree index branch block中只包含先导列键值信息,并不包含非先导列键值信息,而且还dump了branch b ...

  9. Oracle 12C -- 基于sequence的列的默认值

    12C支持先创建一个sequence,然后再将该sequence指定为某个列的值的默认表达式. 和"identity column"具有以下不同点: ·对列的个数没有限制 ·seq ...

随机推荐

  1. Java Script 简介

    Java Script 简介 JavaScript 是世界上最流行的编程语言. 这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备.JavaScrip ...

  2. SourceTree提交不了,报git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags origin master:master

    刚下载好的Soucetree,拉好项目代码却提交不了,害的我百度了好一小会,下面我把我自己最终的解决方案介绍给大家,希望对你们有用. 首先打开 下载好的git 输入命令  ssh-keygen -t  ...

  3. 记一次yii2 上传文件

    1 view渲染 <form action="../src/website/import/report-flow" method="post" encty ...

  4. java 诊断工具——Arthas

    该说不说!小编做的这些功能,最讨厌的就是优化!某些前辈大佬写的代码小辈我实在不敢恭维!那逻辑!那sql! 接下来!今天的主角就登场了,阿里巴巴最近开源出来的一个针对 java 的工具,主要是针对 ja ...

  5. html转化为图片下载

    业务需求:按照客户要求把排课表转化为图片下载到本地.一个月到排课有很多.所以图片会很大 <!DOCTYPE html> <html lang="en"> & ...

  6. Vue随笔记录

    一.创建Vue步骤(VS Code)    1.全局安装       npm install -g vue-cli 2.新建项目    vue init webpack "project-n ...

  7. 移动端与web端的测试点的差别

    单纯从功能测试的层面上来讲的话,APP 测试.web 测试 在流程和功能测试上是没有区别的.根据两者载体不一样,则区别如下:系统结构方面web项目,b/s架构,基于浏览器的:web测试只要更新了服务器 ...

  8. Hillstone防火墙sslvpn配置与使用

    1.山石的sslvpn称为Secure Connect VPN,即scvpn. 2.WEB界面登陆防火墙,“用户”,“AAA服务器”,新建用户: 3.定义源IP池 即用户通过sslvpn拨号成功后获取 ...

  9. ping不通公网ip时路由器设置

    可能是路由器里设置了wan口禁ping了 另外,NAT地址转换不要动,默认是开启的 主服务器上防火墙关掉或者设置好访问规则 默认的80端口是不能用的,需要设置一个其它的端口

  10. HTTP协议转码

    为什么要有转义的功能? 一些特殊字符需要转义,才能被访问,否则变为空格 UrlEnCode与UrlDeCode 有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的 ...