代码之家  ›  专栏  ›  技术社区  ›  fuentesjr

什么SQL查询可以将所有具有2列子行的行作为重复项列出?

  •  4
  • fuentesjr  · 技术社区  · 16 年前

    我有一个具有冗余数据的表,我正在尝试识别所有具有重复子行的行(因为缺少更好的字)。我指的是考虑 COL1 COL2 只有。

    所以假设我有这样的东西:

     COL1   COL2   COL3
     ---------------------
     aa     111    blah_x
     aa     111    blah_j
     aa     112    blah_m
     ab     111    blah_s
     bb     112    blah_d
     bb     112    blah_d
     cc     112    blah_w
     cc     113    blah_p
    

    我需要一个返回此信息的SQL查询:

     COL1   COL2   COL3
     ---------------------
     aa     111    blah_x
     aa     111    blah_j
     bb     112    blah_d
     bb     112    blah_d
    
    10 回复  |  直到 5 年前
        1
  •  8
  •   Blorgbeard    16 年前

    这对你有用吗?

    select t.* from table t
    left join ( select col1, col2, count(*) as count from table group by col1, col2 ) c on t.col1=c.col1 and t.col2=c.col2
    where c.count > 1
    
        2
  •  5
  •   Community clintgh    7 年前

    对于列出的数据,无法进行查询。第5行和第6行中的数据本身并不明显。

    假设您的表名为“quux”,如果您从以下内容开始:

    SELECT a.COL1, a.COL2, a.COL3 
    FROM quux a, quux b
    WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.COL3 <> b.COL3
    ORDER BY a.COL1, a.COL2
    

    最后你会得到这个答案:

     COL1   COL2   COL3
     ---------------------
     aa     111    blah_x
     aa     111    blah_j
    

    这是因为第5行和第6行的col3值相同。任何返回两行5&6的查询也将返回此数据集中所有行的重复项。

    另一方面,如果您有主键(ID),则可以使用此查询:

    SELECT a.COL1, a.COL2, a.COL3
    FROM quux a, quux b
    WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.ID <> b.ID
    ORDER BY a.COL1, a.COL2
    

    [编辑以简化WHERE子句]

    你会得到你想要的结果:

    COL1   COL2   COL3
    ---------------------
    aa     111    blah_x
    aa     111    blah_j
    bb     112    blah_d
    bb     112    blah_d
    

    我刚在SQLServer2000上测试过这个,但是您应该在任何现代的SQL数据库上看到相同的结果。

    blorgbeard 证明了我 wrong --对他有好处!

        3
  •  4
  •   Jerub    16 年前

    像这样加入你自己:

    SELECT a.col3, b.col3, a.col1, a.col2 
    FROM tablename a, tablename b
    WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3
    

    如果您使用的是PostgreSQL,那么可以使用OID使其返回较少的重复结果,如下所示:

    SELECT a.col3, b.col3, a.col1, a.col2 
    FROM tablename a, tablename b
    WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3
      AND a.oid < b.oid
    
        4
  •  2
  •   dacracot    16 年前

    没有现成的数据库来测试这个,但我认为它应该可以工作…

    select
      *
    from
      theTable
    where
      col1 in
        (
        select
          col1
        from
          theTable
        group by
          col1||col2
        having
          count(col1||col2) > 1
        )
    
        5
  •  2
  •   Paul Tomblin    16 年前

    我的天真尝试是

    select a.*, b.* from table a, table b where a.col1 = b.col1 and a.col2 = b.col2 and a.col3 != b.col3;
    

    但这将返回所有行两次。我不知道你怎么能把它限制在只归还一次。如果有主键,可以添加“and a.pkey<b.pkey”。

    就像我说的,这不优雅,可能有更好的方法来做到这一点。

        6
  •  2
  •   Jonathan Schuster    16 年前

    这样的方法应该有效:

    SELECT a.COL1, a.COL2, a.COL3
    FROM YourTable a
    JOIN YourTable b ON b.COL1 = a.COL1 AND b.COL2 = a.COL2 AND b.COL3 <> a.COL3
    

    一般来说,join子句应该包括您认为是“副本”一部分的每一列(本例中为col1和col2),以及至少一列(或尽可能多的列),以消除与自身的行联接(本例中为col3)。

        7
  •  2
  •   IK.    16 年前

    这与自联接非常相似,只是它没有重复项。

    select COL1,COL2,COL3
    from theTable a
    where exists (select 'x'
                  from theTable b
                  where a.col1=b.col1
                  and   a.col2=b.col2
                  and   a.col3<>b.col3)
    order by col1,col2,col3
    
        8
  •  1
  •   Kyle Dyer    16 年前

    这是你如何找到副本的方法。在Oracle10g中使用您的数据进行测试。

    从TST选择* 其中(col1,col2)in (从TST组中选择col1,col2,按col1,col2,计数为(*)>1)

        9
  •  0
  •   pappes    16 年前

    选择col1、col2、col3

    从表

    按col1、col2、col3分组

    计数(*)>1

        10
  •  0
  •   David Aldridge    16 年前

    忘记联接--使用分析函数:

    select col1, col2, col3
    from
    (
    select col1, col2, col3, count(*) over (partition by col1, col2) rows_per_col1_col2
    from table
    )
    where rows_per_col1_col2 > 1