我的数据库中有数据表结构及部分数据如下:
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可以查询到这些不正常的数据急用 ,先谢谢各位了

解决方案 »

  1.   

    那么它的所有记录中的yxq_q及yxq_z必须是衔接的 
    不好意思真的看不出来有什么衔接的
      

  2.   

    不好意思,可能是我没有说清楚
    第一条记录的yxq_z是2006.12.31,那么下一条记录的yxq_q必须是2007.1.1,而且第一条记录中的YXQ_Q与第二条记录中的YXQ_Z恰好构成这两条记录中的zxq_q及zxq_z所指定的区间
      

  3.   

    你的意思是不是:1 每一条记录(yxq_q,yxq_z)不会与另一条的时间段相交
    2 下一个时间段时间开始必须为前一个时间段结束时间的后一天找出不满足上面的记录?
      

  4.   

    to nb95463034:
       是这个意思,有办法实现吗
      

  5.   

    也就是说这两条记录对ZXQ_Q及ZXQ_Z所确定的期间进行了拆分,没有人可以帮忙吗?自己顶一下吧
      

  6.   

    select distinct t.*,m.yxq_q from aa t,aa m where t.name=m.name 
    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)
    试一试吧
      

  7.   

    先把表中的日期转换为YYYYMMDD格式
    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天的记录,即可以将满足条件的记录全部取出。最外层将不在子查询中的记录列出。
      

  8.   

    日期函数可以直接用,试试这个
    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天的记录,即可以将满足条件的记录全部取出。最外层将不在子查询中的记录列出。
      

  9.   

    加条测试纪录,yzq_q特地从上一条的的yzq_z跳过一天
    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 上条纪录不存在 下条纪录正常
      

  10.   

    这个语句里的
    LAG (yxq_z, 1, yxq_q - 1)表示取当前纪录的上一条纪录的yzq_z,如果取不到的话,就默认是当前纪录的yxq_q-1天,这样是保证数据表的第一条纪录不会判断有问题(第一条纪录肯定没有上一条纪录的)
    同理lead是取后一条,这样最后条也不有问题(最后条肯定没有下一条纪录)然后做判断,如果当前纪录的yxq_q-前一天的yxq_z,超过一天(这里有个前提,你的日期都是到日的,没有小时分秒的),说明不连续,当中有断的
    同理也对后一条做判断
    只要满足没有前一条或者后一条纪录的就显示出来
      

  11.   

    to hebo2005:
        谢谢你的解答。不过我只要得到数据不完整的name就可以了。另外如果数据完整的话,那么前一条记录的
    yxq_q与后一条记录的yxq_z所构成的期间恰好是zxq_q与zxq_z确定的期间
      

  12.   

    其实查询要满足的条件就是如果某个人存在YXQ_Q不等于ZXQ_Q的记录,那么再判断他是否缺少记录
      

  13.   

    这个简单了,名字只要在外面只显示NAMe就行了
    里面这层已经把基本数据取出来了,你可以再加了上一条纪录的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也有了,你做比较应该好做了吧