A表:A    B    C    D 
      1   ab    a    q
      2   ab    q    a
      3   ab    e    d
      4   ab    d    e
      5   pd    n    m
      6   pd    m    n
      7   pd    v    b
      8   pd    b    v
      9   cd    f    h
     10   cd    h    f
目的是相当得到结果:
     A    B    C    D 
    1   ab    a    q
    3   ab    e    d
    5   pd    n    m
    7   pd    v    b
    9   cd    f    h
数据就是这样
还有就是表中只有BCD三个字段  后来将rowid作为主键(也就是这里的A列)

解决方案 »

  1.   

    使用分析函数LAG   select m.a, m.b, m.c, m.d
         from (select a,
                      b,
                      c,
                      d,
                      concat(c, d) r,
                      lag(concat(d, c), 1, null) over(order by a) re
                 from t) m
        where m.r <> m.re
           or m.re is null         A B  C D
    ---------- -- - -
             1 ab a q
             3 ab e d
             5 pd n m
             7 pd v b
             9 cd f h
      

  2.   

    这个貌似A字段是NUMBER类型的才可以  如果A字段是VARCHAR2类型的要怎么处理下呢 表中其实没有A 字段 也就是主键  后来直接把rowid做的主键  这个怎么处理下才好呢  比如说新建一个主键列 
      

  3.   

    不一定要是NUMBER类型啊,可以用VARCHAR2类型的,
    或者你可以使用ROWNUM虚拟一个列出来。
    这个很灵活了
      

  4.   

    这个varchar2的刚试了下只去重了一部分  还有一部分没有去掉 (如果A字段是varchar2类型的) 
    后来把A字段改为了NUMBER类型的 去重就没有问题了 
    关于rownum虚拟列的问题,这个疏忽了  只钻到了rowid上 将rowid虚拟了一列 忘记还有rownum  多谢大神啊  哈哈 
      

  5.   

    嗯,如果a是VARCHAR2类型的话是有点问题,它会按字符的顺序排序,不过只要不重复也没什么影响吧?如果你是数字的话,就TO_NUMBER一下咯
      

  6.   

    哦  我刚试了下  为什么我的这种数据就不可以了呢 
    目前字段类型依次为:NUMBER  VARCHAR2  VARCHAR2   VARCHAR2  是不是LAG里面的参数不合适啊 能不能稍微说下那个参数的值啊  以前没见到过这个函数  谢谢了 
      

  7.   

    学习了lag函数,以前只知道有这个函数,今天总算见到其用法了
      

  8.   

       with t as(
         select 1 A,'ab' B,'a' C,'q' D from dual
         union all
         select 2,'ab','q','a' from dual
         union all
         select 3,'ab','e','d' from dual
         union all
         select 4,'ab','d','e' from dual
         union all
         select 5,'pd','n','m' from dual
         union all
         select 6,'pd','m','n' from dual
         union all
         select 7,'pd','v','b' from dual
         union all
         select 8,'pd','b','v' from dual
         union all
         select 9,'cd','f','h' from dual
         union all
         select 10,'cd','h','f' from dual
         )
         select *
           from t t2
          where exists (select 1
                   from t t1
                  where t1.a > t2.a
                    and t1.b = t2.b
                    and greatest(t1.c, t1.d) = greatest(t2.c, t2.d)
                    and least(t1.c, t1.d) = least(t2.c, t2.d))
             A B  C D
    ---------- -- - -
             1 ab a q
             3 ab e d
             5 pd n m
             7 pd v b
             9 cd f h
      

  9.   

    终于解决了问题啊  哈哈 厉害厉害  lag函数对我举的例子来说是实用的  但是到真实数据里面却不可以 回去还得在研究研究  但是您的这个语句确实厉害  一下子就解决了
      

  10.   

    他那个lag是需要排序,然后判断相邻的记录是否相同,我那个不需要顺序相邻
      

  11.   

    他的a列也不能为字符的 不然也会有问题的
    ,不过这种方法算是学习了
    你不要直接用ROWNUM,我的你可以这样不用ROWNUM,TO_NUMBER(AREA_KEY)这样.
      

  12.   

    rownum虚拟的主键列,用lag在数据库中操作真实数据时候只去重了几十条 上面贴的那两张图就是数据库里面的数据 ,回去再研究下 哈哈 谢谢了
      

  13.   

    确实如此,还是大大经验丰富啊,你的SQL比我通用多了。。
      

  14.   

    还是有点问题,如果有t的B,C,D列有重复的就不准了。with t as
     (select 1 as a, 'ab' as b, 'a' as c, 'q' as d
        from dual
      union all
      select 2 as a, 'ab' as b, 'q' as c, 'a' as d
        from dual
      union all
      select 3 as a, 'ab' as b, 'e' as c, 'd' as d
        from dual
      union all
      select 4 as a, 'ab' as b, 'd' as c, 'e' as d
        from dual
      union all
      select 5 as a, 'pd' as b, 'n' as c, 'm' as d
        from dual
      union all
      select 6 as a, 'pd' as b, 'm' as c, 'n' as d
        from dual
      union all
      select 7 as a, 'pd' as b, 'm' as c, 'n' as d
        from dual
      union all
      select 8 as a, 'pd' as b, 'm' as c, 'n' as d
        from dual
      union all
      select 9 as a, 'pd' as b, 'n' as c, 'm' as d
        from dual
      union all
      select 10 as a, 'cd' as b, 'm' as c, 'n' as d
        from dual
      union all
      select 11 as a, 'ab' as b, 'a' as c, 'q' as d from dual)
    select *
      from t t2
     where exists (select 1
              from t t1
             where t1.a > t2.a
               and t1.b = t2.b
               and greatest(t1.c, t1.d) = greatest(t2.c, t2.d)
               and least(t1.c, t1.d) = least(t2.c, t2.d))
     order by a结果:         A B  C D
    ---------- -- - -
             1 ab a q
             2 ab q a
             3 ab e d
             5 pd n m
             6 pd m n
             7 pd m n
             8 pd m n已选择7行。
      

  15.   

    借用楼上大哥的数据啦。
    SELECT A, B, C, D
      FROM (select A,
                   B,
                   C,
                   D,
                   min(A) keep(DENSE_RANK first ORDER BY A) over(partition by B, C, D) AS A2
              FROM T T1
             WHERE EXISTS (SELECT 1
                      FROM T T2
                     WHERE T2.A > T1.A
                       AND T2.C = T1.D
                       AND T2.D = T1.C))
     WHERE A = A2
      

  16.   

    改一下。SELECT A, B, C, D
      FROM (select A,
                   B,
                   LEAST(T1.C, T1.D) AS C,
                   GREATEST(T1.C, T1.D) AS D,
                   min(A) keep(DENSE_RANK first ORDER BY A) over(partition by B, GREATEST(C, D), LEAST(C, D)) AS A2
              FROM T T1)
     WHERE A = A2================================================
    1 3 ab d e
    2 1 ab a q
    3 10 cd m n
    4 5 pd m n
    最下面的也要去掉。不考虑‘CD’,'PD'不相同情况,可以把partition by B的B去了。
      

  17.   

    弄错字段了,再改。SELECT A, B, C, D
      FROM (select T.*,
                   min(A) keep(DENSE_RANK first ORDER BY A) over(partition by B, GREATEST(C, D), LEAST(C, D)) AS A2
              FROM T)
     WHERE A = A2
     ORDER BY A
      

  18.   

    对于存在B,C,D都重复,以及A,B唯一,且只存在一条记录的场景有问题。

    A  B C  D
    1 ab  a q
    2 ab  a q
    3 ab  q a
    4 cd  c d