【问题标题】:Fast way to eyeball possible duplicate rows in a table?快速查看表格中可能重复的行的方法?
【发布时间】:2010-12-20 03:39:13
【问题描述】:

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

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

我有一张相当大的桌子,大约有 400 万行和 50 多列。它有一个应该是唯一的列,Episode。不幸的是,Episode 不是独特的 - 这背后的逻辑是偶尔会改变行中的其他字段,尽管 Episode 被重复。但是,有一个实际上唯一的列,Sequence。

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

我希望创建一个显示剧集编号的表格,并为每个表格列创建一个列,标识两侧的值,它们的不同之处:

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 是不同的,同一行会以不同的方式弹出。

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

【问题讨论】:

  • @Margaret:抱歉,我没听懂有关序列列的部分。我更新了我的答案。

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


【解决方案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 的排序。

更新 我没有发现序列列将是一个唯一值,但在这种情况下,您必须提供您想要查看的所有列的列表。即:

  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。一旦从输出中省略了序列列,重复项就会变得明显。

【讨论】:

  • 但是 SELECT DISTINCT 不会像我说的那样被 Sequence 列弄糊涂吗?
  • 感到困惑?现在我很困惑。 DISTINCT * 只是 GROUP BY [all the columns in your query] 的同义词
  • 重点是每一行不同的——我提到的序列列确保了这一点。这至少部分是问题的根源 - 该行可能在其他方面相同,但 SELECT DISTINCT 不会检测到,因为(唯一)序列值在那里。
【解决方案2】:

您可以这样做,而不是输入所有 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'

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

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...

【讨论】:

    【解决方案3】:
    select count distinct ....
    

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

    【讨论】:

    • 我之前确实尝试过使用 count distinct - 我需要使用什么样的黑魔法才能让它与多列一起使用?当我尝试“SELECT COUNT(DISTINCT Column1, Column2, ...) FROM Table”时,我得到“',' 附近的语法不正确。”
    • @Margaret:COUNT 不支持 2+ 列
    • 用你的列替换 ... select count distinct a, b, c
    【解决方案4】:

    我认为你想要这样的东西:

    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 &lt; b.Sequence,否则您会得到重复的非重复项。

    【讨论】:

    • 但是 OP 知道有重复的剧集值 - 问题是如何获取一个列表来确定要保留哪些重复项。
    【解决方案5】:

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

    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 列是剧集。这样,当数据与上面的行不同时(只要两行的情节值相同),您就会获得视觉突出显示。

    【讨论】:

      【解决方案6】:

      为每一行生成并存储一个散列键,这样散列值反映了你的 同一性的定义。根据行的复杂性,更新 hash 可能是修改行的简单触发器。

      查询哈希键的重复项,这是您“很可能”相同的行。

      【讨论】:

        猜你喜欢
        • 2019-02-11
        • 2016-12-09
        • 2012-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多