我正在清理没有主键的数据库表(我知道,我知道,他们在想什么?)。我无法添加主键,因为列中的副本将成为键。重复值来自两行中的一行,这两行在所有方面都相同。我无法通过GUI删除该行(在本例中是MySQL Workbench,但我正在寻找一种与数据库无关的方法),因为它拒绝在没有主键(或至少是UQ NN列)的表上执行任务,并且我无法添加主键,因为列中的副本将成为键。重复值来自一个......
如何删除其中一对双胞胎?
答案 0 :(得分:52)
SET ROWCOUNT 1
DELETE FROM [table] WHERE ....
SET ROWCOUNT 0
这只会删除两个相同行中的一行
答案 1 :(得分:21)
解决问题的一个方法是创建一个具有相同模式的新表,然后执行:
INSERT INTO new_table (SELECT DISTINCT * FROM old_table)
然后只需重命名表格。
您当然需要大约相同的空间,因为您的磁盘需要备用磁盘才能执行此操作!
效率不高,但非常简单。
答案 2 :(得分:19)
请注意,MySQL有自己的DELETE
扩展名DELETE ... LIMIT
,它的工作方式与LIMIT
DELETE FROM some_table WHERE x="y" AND foo="bar" LIMIT 1;
{{1}}的通常方式相同:http://dev.mysql.com/doc/refman/5.0/en/delete.html
DELETE的特定于MySQL的LIMIT row_count选项告诉服务器 返回控件之前要删除的最大行数 客户端。这可以用于确保给定的DELETE语句 不花太多时间。您只需重复删除即可 声明直到受影响的行数小于LIMIT 值。
因此,您可以使用{{1}}请注意,没有一种简单的方法可以说“删除除一个以外的所有内容” - 只需继续检查是否仍有行重复。
答案 3 :(得分:10)
对于PostgreSQL,你可以这样做:
DELETE FROM tablename
WHERE id IN (SELECT id
FROM (SELECT id, ROW_NUMBER()
OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
FROM tablename) t
WHERE t.rnum > 1);
column1,column2,column3将设置具有重复值的列。
参考here。
答案 4 :(得分:6)
delete top(1)适用于Microsoft SQL Server(T-SQL)。
答案 5 :(得分:5)
这可以使用CTE和//Init
float maxs[10+1];
for(int i=0; i<10+1; i++){
maxs[i] = -inf;
}
for(int i=0; i<size; i++){
//Is it higher than the element 0?
if(data[i] > maxs[0]){
maxs[0] = data[i];
for(int j=0; j<10; j++){
if(maxs[j] > maxs[j+1])
swap(maxs[j], maxs[j+1]);
else break;
}
}
}
函数完成,如下所示:
ROW_NUMBER()
将列添加到ORDER BY非常方便,但除非您优先选择要删除的行,否则不需要。这也将处理重复记录的所有实例,而不是强制您一次删除一行。
答案 6 :(得分:4)
尝试过LIMIT 1?这只会删除与您的DELETE
查询相符的1行
DELETE FROM `table_name` WHERE `column_name`='value' LIMIT 1;
答案 7 :(得分:2)
你可以使用max,这与我的情况相关。
file-path
请务必首先测试您的搜索结果,并在您的&#34; clausule。有了这么大的删除查询,您可能需要先更新数据库。
答案 8 :(得分:1)
在我的情况下,我可以获取GUI以给我一行相关行的值(或者,我可以手动完成)。根据一位同事的建议,我保留了他的债务,我用它来创建一个INSERT声明:
INSERT
'ID1219243408800307444663', '2004-01-20 10:20:55', 'INFORMATION', 'admin' (...)
INTO some_table;
我测试了insert语句,所以我现在有了三元组。最后,我运行了一个简单的DELETE来删除所有这些......
DELETE FROM some_table WHERE logid = 'ID1219243408800307444663';
然后再插入INSERT,留下一行,以及主键的明亮可能性。
答案 9 :(得分:1)
如果你可以添加像
这样的列 ALTER TABLE yourtable ADD IDCOLUMN bigint NOT NULL IDENTITY (1, 1)
这样做。
然后计算按问题列分组的行数,其中count> 1,这将识别您的双胞胎(或三胞胎或其他)。
然后选择您的问题列,其内容等于上面标识的内容,并检查IDCOLUMN中的ID。
从您的表中删除IDCOLUMN等于其中一个ID。
答案 10 :(得分:1)
这适用于PostgreSQL
DELETE FROM tablename WHERE id = 123 AND ctid IN (SELECT ctid FROM tablename WHERE id = 123 LIMIT 1)
答案 11 :(得分:0)
我在表中添加了一个Guid列,并将其设置为每行生成一个新的id。然后我可以使用GUI删除行。
答案 12 :(得分:0)
在 PostgreSQL 中,有一个名为ctid
的隐式列。请参阅wiki。所以你可以自由使用以下内容:
WITH cte1 as(
SELECT unique_column, max( ctid ) as max_ctid
FROM table_1
GROUP BY unique_column
HAVING count(*) > 1
), cte2 as(
SELECT t.ctid as target_ctid
FROM table_1 t
JOIN cte1 USING( unique_column )
WHERE t.ctid != max_ctid
)
DELETE FROM table_1
WHERE ctid IN( SELECT target_ctid FROM cte2 )
我不确定在有可能进行并发更新时使用它是多么安全。因此,人们可能会发现在实际进行清理之前制作LOCK TABLE table_1 IN ACCESS EXCLUSIVE MODE;
是明智的。
答案 13 :(得分:0)
如果要删除多个重复的行,并且所有字段都相同,没有不同的id,表没有主键,一种选择是将具有不同的重复行保存在新表中,删除所有重复行并插入排回来。如果表很大而重复的行数很小,这将很有帮助。
--- col1 , col2 ... coln are the table columns that are relevant.
--- if not sure add all columns of the table in the select bellow and the where clause later.
--- make a copy of the table T to be sure you can rollback anytime , if possible
--- check the @@rowcount to be sure it's what you want
--- use transactions and rollback in case there is an error
--- first find all with duplicate rows that are identical , this statement could be joined
--- with the first one if you choose all columns
select col1,col2, --- other columns as needed
count(*) c into temp_duplicate group by col1,col2 having count(*) > 1
--- save all the rows that are identical only once ( DISTINCT )
insert distinct * into temp_insert from T , temp_duplicate D where
T.col1 = D.col1 and
T.col2 = D.col2 --- and other columns if needed
--- delete all the rows that are duplicate
delete T from T , temp_duplicate D where
T.col1 = D.col1 and
T.col2 = D.col2 ---- and other columns if needed
--- add the duplicate rows , now only once
insert into T select * from temp_insert
--- drop the temp tables after you check all is ok
答案 14 :(得分:0)
如果像我一样,您不想列出数据库的所有列,则可以将每一行转换为JSONB并以此进行比较。
(注意:这效率极低-请注意!)
select to_jsonb(a.*), to_jsonb(b.*)
FROM
table a
left join table b
on
a.entry_date < b.entry_date
where (SELECT NOT exists(
SELECT
FROM jsonb_each_text(to_jsonb(a.*) - 'unwanted_column') t1
FULL OUTER JOIN jsonb_each_text(to_jsonb(b.*) - 'unwanted_column') t2 USING (key)
WHERE t1.value<>t2.value OR t1.key IS NULL OR t2.key IS NULL
))
答案 15 :(得分:0)
假设我们要删除重复的记录,只保留 Employee 表中的 1 个唯一记录 - Employee(id,name,age)
delete from Employee
where id not in (select MAX(id)
from Employee
group by (id,name,age)
);