我的数据库中有数据表结构及部分数据如下:
name yxq_q yxq_z zxq_q zxq_z
a 2006.5.1 2006.12.31 2006.5.1 2007.4.30
a 2007.1.1 2007.4.30 2006.5.1 2007.4.30也就是说相同的name如果有多条记录,那么它的所有记录中的yxq_q及yxq_z必须是衔接的如果由于一些原因有可能导致以上数据成为如下异常情况,如
name yxq_q yxq_z zxq_q zxq_z
a 2007.1.1 2007.4.30 2006.5.1 2007.4.30也就是说丢失了上一条记录,那么如何使用SELECT可以查询到这些不正常的数据急用 ,先谢谢各位了
name yxq_q yxq_z zxq_q zxq_z
a 2006.5.1 2006.12.31 2006.5.1 2007.4.30
a 2007.1.1 2007.4.30 2006.5.1 2007.4.30也就是说相同的name如果有多条记录,那么它的所有记录中的yxq_q及yxq_z必须是衔接的如果由于一些原因有可能导致以上数据成为如下异常情况,如
name yxq_q yxq_z zxq_q zxq_z
a 2007.1.1 2007.4.30 2006.5.1 2007.4.30也就是说丢失了上一条记录,那么如何使用SELECT可以查询到这些不正常的数据急用 ,先谢谢各位了
不好意思真的看不出来有什么衔接的
第一条记录的yxq_z是2006.12.31,那么下一条记录的yxq_q必须是2007.1.1,而且第一条记录中的YXQ_Q与第二条记录中的YXQ_Z恰好构成这两条记录中的zxq_q及zxq_z所指定的区间
2 下一个时间段时间开始必须为前一个时间段结束时间的后一天找出不满足上面的记录?
是这个意思,有办法实现吗
and t.yxq_q<=m.yxq_q and t.yxq_z+1<>m.yxq_q and t.yxq_q<>t.zxq_q
and t.name not in(select t.name from aa t,aa m where t.name=m.name
and t.yxq_q<m.yxq_q)
试一试吧
select * from table t1
where not exist
(select * from table t2
where t1.name=t2.name
and t1.yxq_q = t2.yxq_q
and t1.yxq_z=t2.yxq_z
start with yxq_q = 'YYYYMMDD'--最开始的日期
connected by perior yxq_q = to_char(to_date(yxq_z,'YYYYMMDD')-1,'YYYYMMDD'))
该SQL子查询意思是选取yxq_q为最开始日期的记录,然后搜索yxq_q对应到上条记录yxq_z少1天的记录,即可以将满足条件的记录全部取出。最外层将不在子查询中的记录列出。
select * from table t1
where not exist
(select * from table t2
where t1.name=t2.name
and t1.yxq_q = t2.yxq_q
and t1.yxq_z=t2.yxq_z
start with yxq_q = 'YYYY.MM.DD'--最开始的日期
connected by perior yxq_q = to_char(to_date(yxq_z,'YYYY.MM.DD')-1,'YYYY.MM.DD'))
该SQL子查询意思是选取yxq_q为最开始日期的记录,然后搜索yxq_q对应到上条记录yxq_z少1天的记录,即可以将满足条件的记录全部取出。最外层将不在子查询中的记录列出。
WITH a AS
(SELECT 'a' NAME, TO_DATE ('2006.5.1', 'yyyy.mm.dd') yxq_q,
TO_DATE ('2006-12-31', 'yyyy-mm-dd') yxq_z,
TO_DATE ('2006-5-1', 'yyyy-mm-dd') zxq_q,
TO_DATE ('2007-4-30', 'yyyy-mm-dd') zxq_z
FROM DUAL zxq_z
UNION ALL
SELECT 'a', TO_DATE ('2007-1-1', 'yyyy-mm-dd'),
TO_DATE ('2007-4-30', 'yyyy-mm-dd'),
TO_DATE ('2006-5-1', 'yyyy-mm-dd'),
TO_DATE ('2007-4-30', 'yyyy-mm-dd')
FROM DUAL
UNION ALL
SELECT 'a', TO_DATE ('2007-5-2', 'yyyy-mm-dd'),
TO_DATE ('2007-5-31', 'yyyy-mm-dd'),
TO_DATE ('2006-5-1', 'yyyy-mm-dd'),
TO_DATE ('2007-4-30', 'yyyy-mm-dd')
FROM DUAL)SELECT aa.NAME, aa.yxq_q, aa.yxq_z, aa.zxq_q, aa.zxq_z,
DECODE (ABS (yxq_q - pre_day),
1, '上条纪录正常',
'上条纪录不存在'
) pre_if_erreo,
DECODE (ABS (after_day - yxq_z),
1, '下条纪录正常',
'下条纪录不存在'
) after_if_erreo
FROM (SELECT a.*, LAG (yxq_z, 1, yxq_q - 1) OVER (ORDER BY yxq_z) pre_day,
LEAD (yxq_q, 1, yxq_z + 1) OVER (ORDER BY yxq_z) after_day
FROM a) aa
WHERE ABS (yxq_q - pre_day) > 1 OR ABS (after_day - yxq_z) > 1结果
Row# NAME YXQ_Q YXQ_Z ZXQ_Q ZXQ_Z PRE_IF_ERREO AFTER_IF_ERREO1 a 2007/1/1 2007/4/30 2006/5/1 2007/4/30 上条纪录正常 下条纪录不存在
2 a 2007/5/2 2007/5/31 2006/5/1 2007/4/30 上条纪录不存在 下条纪录正常
LAG (yxq_z, 1, yxq_q - 1)表示取当前纪录的上一条纪录的yzq_z,如果取不到的话,就默认是当前纪录的yxq_q-1天,这样是保证数据表的第一条纪录不会判断有问题(第一条纪录肯定没有上一条纪录的)
同理lead是取后一条,这样最后条也不有问题(最后条肯定没有下一条纪录)然后做判断,如果当前纪录的yxq_q-前一天的yxq_z,超过一天(这里有个前提,你的日期都是到日的,没有小时分秒的),说明不连续,当中有断的
同理也对后一条做判断
只要满足没有前一条或者后一条纪录的就显示出来
谢谢你的解答。不过我只要得到数据不完整的name就可以了。另外如果数据完整的话,那么前一条记录的
yxq_q与后一条记录的yxq_z所构成的期间恰好是zxq_q与zxq_z确定的期间
里面这层已经把基本数据取出来了,你可以再加了上一条纪录的yxq_q LAG (yxq_z, 1, yxq_q - 1) OVER (ORDER BY yxq_z) pre_day_q,SELECT a.*, LAG (yxq_z, 1, yxq_q - 1) OVER (ORDER BY yxq_z) pre_day,
LEAD (yxq_q, 1, yxq_z + 1) OVER (ORDER BY yxq_z) after_day
FROM a
你在外面做相应的判断就行了,
比如说
另外如果数据完整的话,那么前一条记录的
yxq_q与后一条记录的yxq_z所构成的期间恰好是zxq_q与zxq_z确定的期间
此时一条纪录相当于有上条纪录的yxq_q,yxq_z和本条纪录的yxq_q,yxq_z,后面的zxq_q与zxq_z也有了,你做比较应该好做了吧