快速查看表中可能重复行的方法?

时间:2009-11-25 03:52:51

标签: sql sql-server sql-server-2005 tsql duplicate-removal

类似:How can I delete duplicate rows in a table

我觉得这是不可能的,我将不得不以乏味的方式去做,但我会看到你们要说的话。

我有一张相当大的桌子,大约有400万行,还有50多列。它有一个应该是唯一的专栏,Episode。不幸的是,Episode是唯一 - 这背后的逻辑是偶尔其他领域的变化,尽管Episode被重复。但是,有一个实际唯一列,Sequence。

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

我希望创建一个显示Episode编号的表格,以及每个表格列的一列,标识两边的值,它们是不同的:

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

(这可能充满了漏洞,但我希望能突出改变价值观的想法。)

不幸的是,对50列进行类似的查询非常痛苦。显然,如果它只使用一次,它并不一定是坚如磐石的,但与此同时,代码的复制意味越多,就越有可能错过一些东西。据我所知,我不能只搜索DISTINCT,因为Sequence是不同的,同一行会弹出不同的。

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

6 个答案:

答案 0 :(得分:1)

使用:

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

DISTINCT只是编写GROUP BY所涉及的所有列的简写。按所有列进行分组将显示与此案例中与剧集列关联的所有唯一记录。因此,存在无法准确计算重复数的风险,但您将拥有这些值,以便您可以决定在达到这一点时要删除的内容。

50列是很多,但设置ORDER BY将允许您关注列表。如果您不想构建ORDER BY,并使用Excel的排序,另一种方法是将数据导出到Excel。

<强>更新 我没有意识到序列列将是一个唯一值,但在这种情况下,您必须提供您想要查看的所有列的列表。 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。从输出中省略序列列后,重复项将变得明显。

答案 1 :(得分:1)

您可以执行以下操作,而不是输入所有50列:

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

然后将它们粘贴到一个查询中,该查询按所有列分组EXCEPT序列,并按计数过滤&gt; 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'

您将这些连接参数插入此查询:

select * from YourTable t1 
inner join (
select 
      count(episode) 'epcount'
    , col1
    , col2
    , col3
    , ...
    from YourTable
    group by
      col1
    , col2
    , col3
    , ...
    having count(episode) > 1
) t2 on 

...plug in all those join parameters here...

答案 2 :(得分:0)

select count distinct ....

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

答案 3 :(得分:0)

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

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,否则您将获得重复的非重复项。

答案 4 :(得分:0)

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

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栏是剧集。这样,当数据与上面的行不同时(只要两行对于剧集具有相同的值),您将获得视觉突出显示。

答案 5 :(得分:0)

为每一行生成并存储一个哈希键,其设计使哈希值与您的哈希值相同 相同的定义。根据行的复杂程度,更新 hash可能是修改行的简单触发器。

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