序运算,找出不符合连续递增的异常
【问题】
ID DDATE
1 2013/5/7
2 2013/8/6
3 2013/6/12
4 2013/12/1
一个表当中 ID 1 2 3 4 这样,时间也应该是从小到大,现在想把时间不是从小到大的找出来。 比如:2 2013/8/6和3 2013/6/12 就不对,把这两条找出来
【回答】
按照问题描述,可能有两种情况,一是只比较相邻记录;二是比较当前记录与前后所有记录(如当3比2大但比1小时,应将1 2 3都查出来),在ORACLE中实现这两种情况都要借助窗口函数使用子查询来完成,分别可以这样写:
(1) 只比较相邻:
SELECT id, ddate
FROM (select id,ddate,
lag(ddate,1) over(order by id) as d1,
lead(ddate,1) over(order by id) as d2
from T0042)
WHERE d1 > ddate OR d2 < ddate
(2) 比较所有:
WITH T1 as (
select id,ddate,max(ddate)over(order by id) d1
from t0042),T2 as (
select id,min(ddate)over(order by id desc) d2
from t0042)
select T1.id,T1.ddate
from T2,T1
WHERE T1.id=T2.id and (t1.ddate<>T1.d1 or t1.ddate<>T2.d2)
SQL的写法较复杂难懂,其主要是因为集合无序,要用窗口函数拼出子查询造出次序。如果集合有序的话,上述运算就容易写了。用SPL完成这个运算会直观一些,具体脚本如下:
A |
|
1 |
$select ID,DDATE from t0042 order by ID |
2 |
=A1.select(DDATE<DDATE[-1] || DDATE>min(DDATE[0,1])) |
3 |
=A1.select(DDATE!=max(DDATE[,0]) || DDATE!=min(DDATE[0,])) |
A1:sql取数,按照ID排序
A2:比较相邻,选出比上一个DDATE小,或者比后一个DDATE大的记录
A3:比较所有,选出不比前面所有DDATE都大,或者不比后面所有DDATE都小的记录
写好的脚本如何在应用程序中调用,可以参考Java 如何调用 SPL 脚本