查询以返回除键之外的所有列相等的行

时间:2012-02-10 12:35:14

标签: sql oracle plsql

我有一个表,其中一些行除了键列以外都是其他行的副本。我需要返回所有具有重复项的键值的列表。例如:

(key)
ID       Column_B Column_C Column_D Column_E
1        foo      bar      beyond   belief       
2        foo      bar      beyond   belief  
3        blah     blah2    blah3    blah4       
4        ho       hum      di       dum       
5        foo      bar      beyond   belief 

在这种情况下,我需要查询返回1, 2, and 5,因为这些键在所有其他列中都有重复值。

在这个简化的例子中,我可以使用这样的连接轻松地做到这一点:

SELECT ID
FROM mytable t
INNER JOIN (SELECT Column_B, Column_C, Column_D, Column_E
            FROM mytable
            GROUP BY Column_B, Column_C, Column_D, Column_E
            HAVING COUNT(*) > 1) t2
ON t.Column_B = t2.Column_B
AND t.Column_C = t2Column_C
AND t.Column_D = t2.Column_D
AND t.Column_E = t2.Column_E

但我的'真实'表有很多列(20+),这可能会增长(它是一个非规范化的表格,用于生成快速报告),所以我希望有人可以提出:

  • 更有活力的东西,或
  • 比加入所有列的东西略显笨重。

SQL或PL / SQL都可以..

4 个答案:

答案 0 :(得分:1)

在oracle上我会尝试这样的事情:

select column_a
     , t1.column_b || t1.column_c ... concat_value
from   my_table t1
where  t1.column_b || t1.column_c ... in 
       ( select t2.column_b || t2.column_c ... inner_concat_value
         from   mytable t2
         group by t2.column_a || t2.column_b ...
         having count(*) > 1
       )

我没有运行此查询,但它可能会给你一个想法。请考虑字段之间的分隔符,否则结果可能不正确。

答案 1 :(得分:0)

假设你有stragg(或类似功能),试试这个:

select stragg(to_char(ColumnA))
from my_table
group by Column_B, Column_C, Column_D, Column_E
having count(*) > 1

答案 2 :(得分:0)

如果您不想使用动态SQL,并且您不想加入所有列,我同意这两个最好的事情就是哈希所有其他列在条目时键入主键进入表格,然后单独加入;有一个绝对微不足道的变化,你会得到一个重复。以下内容应该有效:

function checksum( P_Str in varchar2 ) return varchar2 is

   l_CSum dbms_obfuscation_toolkit.raw_checksum;

begin

   if P_Str is null then
      return null;
   else
      dbms_obfuscation_toolkit.md5( input => utl_raw.cast_to_raw(P_Str)
                                  , checksum => l_CSum );
      return l_CSum;
   end if;

end checksum;

答案 3 :(得分:0)

按列顺序选择它们,将该键作为最后一列。

对它进行排序,使副本最终彼此相邻。

使用LAG检查结果集中的adjecent行, 拔下钥匙并将它们保存在桌子上。

报告该表的DISTINCT结果。