快速的方法来检查表中可能的重复行吗?

快速的方法来检查表中可能的重复行吗?

问题描述:

类似的:How can I delete duplicate rows in a table快速的方法来检查表中可能的重复行吗?

我有一种感觉,这是不可能的,我将不得不这样做乏味的方式,但我会看到你们不得不说的。

我有一个很大的桌子,大约400万行,和50多个列。它有一个应该是独一无二的专栏,Episode。不幸的是,Episode是而不是的独特之处 - 背后的逻辑是偶尔其他领域的行会改变,尽管重复了Episode。但是,有一个实际上是唯一列,Sequence。

我想尝试识别具有相同剧集编号的行,但它们之间的内容不同(除了顺序),所以我可以选择出现这种情况的频率,以及是否值得允许或者我应该只用nuke行并忽略可能的轻微差异。

我希望创建一个表中显示了集数,并为每个表列一列,标识双方,他们是不同的价值:

SELECT Episode, 
     CASE WHEN a.Value1<>b.Value1 
      THEN a.Value1 + ',' + b.Value1 
      ELSE '' END AS Value1, 
     CASE WHEN a.Value2<>b.Value2 
      THEN a.Value2 + ',' + b.Value2 
      ELSE '' END AS Value2 
FROM Table1 a INNER JOIN Table1 b ON a.Episode = b.Episode 
WHERE a.Value1<>b.Value1 
     OR a.Value2<>b.Value2 

(那很可能是充满但希望突出显示已更改的值的想法)

不幸的是,对于五十列进行查询是非常痛苦的。显然,如果仅仅使用一次,它不一定是坚如磐石的,但同时代码越多,越可能丢失某些东西。据我所知,我不能只搜索DISTINCT,因为Sequence是不同的,并且同一行将弹出不同的行。

有没有人有一个查询或功能,可能有帮助?要么会输出类似于上面的查询结果,要么是不同的解决方案?正如我所说,现在我没有真的想要删除的重复,只是识别它们。

+0

@玛格丽特:对不起,我没有看到关于序列栏的部分。我更新了我的答案。 – 2009-11-25 05:10:48

一个相对简单的解决方案,小马引发:

SELECT t.* 
FROM Table t 
    INNER JOIN (SELECT episode 
       FROM Table 
       GROUP BY Episode 
       HAVING COUNT(*) > 1 
       ) AS x ON t.episode = x.episode 

然后,复制粘贴到Excel中,并以此作为条件突出显示为整个结果集:

=AND($C2=$C1,A2<>A1) 

列C是插曲。这样,当数据与上面的行不同时(只要这两行对于情节具有相同的值),您将获得视觉高光。

select count distinct .... 

应该向你展示,而不必猜测。您可以通过查看表格定义来获取列,以便复制/粘贴非序列列。

+0

我确实尝试过使用计数不同的早期 - 我需要使用什么样的黑魔法才能使其与多个列一起工作?当我尝试“SELECT COUNT(DISTINCT Column1,Column2,...)FROM Table”I get“在','附近的语法不正确。“ – Margaret 2009-11-25 04:17:33

+0

@Margaret:COUNT不支持2+列 – 2009-11-25 04:18:38

+0

用您的列替换... select count distinct a,b,c – 2009-11-25 14:18:01

用途:

SELECT DISTINCT t.* 
    FROM TABLE t 
ORDER BY t.episode --, and whatever other columns 

DISTINCT仅仅是写一个GROUP BY所有涉及的列的简写。在这种情况下,按所有列进行分组将显示与情节列相关的记录的所有唯一。所以存在没有准确计数重复的风险,但是您将拥有这些值,以便您可以决定在达到该点时要删除的内容。

50列很多,但设置ORDER BY将允许您眼球清单。另一种方法是将数据导出到Excel,如果你不想构造ORDER BY,并使用Excel的排序。

UPDATE 我没听懂序列列将是一个独特的价值,但在这种情况下,你必须提供所有你想看到的列的列表。IE:

SELECT DISTINCT t.episode, t.column1, t.column2 --etc. 
    FROM TABLE t 
ORDER BY t.episode --, and whatever other columns 

有没有符号,可以让你使用t.* but not this one column。一旦序列列从输出中被省略,重复将变得明显。

+0

但是不会SELECT DISTINCT变得困惑Sequence列,就像我在说的那样? – Margaret 2009-11-25 04:22:49

+0

弄糊涂了?现在我很困惑。'DISTINCT *'只是'GROUP BY [查询中的所有列]'的同义词' – 2009-11-25 04:36:30

+0

问题是每行*是*不同的 - 我提到的Sequence列确保了这一点,至少部分是问题的根源 - 行可能是相同的,但SELECT DISTINCT不会检测到,因为(唯一的)序列值在那里。 – Margaret 2009-11-25 04:53:23

我觉得这样的事情是你想要什么:

select * 
from t 
where t.episode in (select episode from t group by episode having count(episode) > 1) 
order by episode 

这会得到具有被复制集的所有行。非重复的行应该相当明显。

当然,如果您有权访问某种脚本,您可以编写脚本来为您生成查询。它看起来非常直截了当。 (即describe t并遍历所有字段)。

此外,你的查询应该有某种排序,如FROM Table1 a INNER JOIN Table1 b ON a.Episode = b.Episode AND a.Sequence < b.Sequence,否则你会得到重复的非重复。

+0

但OP *知道*有重复的情节值 - 问题是如何获得一个列表来确定重复保留与否。 – 2009-11-25 04:37:53

相反打字了所有50列,你可以这样做:

select column_name from information_schema.columns where table_name = 'your table name' 

然后将它们粘贴到一个查询,由所有除顺序列组,和过滤器通过计数> 1:

select 
    count(episode) 
, col1 
, col2 
, col3 
, ... 
from YourTable 
group by 
    col1 
, col2 
, col3 
, ... 
having count(episode) > 1 

这应该给你一个所有具有相同剧集编号的行的列表。 (但是,只有序列和情节号码本身)。这里是揉搓:除了序列和情节之外,您需要将此结果集连接到YourTable,因为在这里没有这些列。

这里是我喜欢使用SQL来生成更多SQL的地方。这应该让你开始:

select 't1.' + column_name + ' = t2.' + column_name 
from information_schema.columns where table_name = 'YourTable' 

你会在这些插件加入参数,这个查询:

​​3210

生成并存储于各行的散列键,这样设计的:哈希值反映您的 相同性的定义。根据行的复杂性,更新 散列可能是修改行的简单触发器。

查询散列键的重复项,它们是“非常可能”相同的行。