类似: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是不同的,同一行会弹出不同的。
有没有人有可能有帮助的查询或功能?要么输出类似于上面的查询结果的东西,要么是不同的解决方案?正如我所说,现在我并不是真的想要删除重复项,只需识别它们。
答案 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可能是修改行的简单触发器。
查询散列键的重复项,这些行是“非常可能”相同的行。