首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从db中删除重复项

问从db中删除重复项
EN

Stack Overflow用户
提问于 2014-09-07 07:43:35
回答 4查看 110关注 0票数 1

我有像下面这样的桌子

代码语言:javascript
复制
id | a_id | b_id | success
--------------------------
1    34      43      1
2    34      84      1
3    34      43      0
4    65      43      1
5    65      84      1
6    93      23      0
7    93      23      0

我想用相同的a_id和b_id删除副本,但我希望保留一条记录。如果可能的话,保存的记录应该与success=1一起保存。因此,例如,表3和表6/7应该删除。怎么做?

我正在使用MySQL 5.1

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-09-07 08:44:57

任务很简单:

  • 查找不应删除的最低记录数。
  • 删除其他记录。

先知的方式,

代码语言:javascript
复制
delete from sample_table where id not in(
select id from
(
 Select id, success,row_number()  
 over (partition by a_id,b_id order by success desc) rown 
 from sample_table
) 
where (success = 1 and rown = 1) or rown=1)

mysql中的解决方案:

将提供不应删除的最小ids。

代码语言:javascript
复制
Select id from (SELECT * FROM report ORDER BY success desc) t 
group by  t.a_id, t.b

o/p:

代码语言:javascript
复制
ID
1
2
4
5
6

您可以删除其他行。

代码语言:javascript
复制
  delete from report where id not in (the above query)

合并后的DML:

代码语言:javascript
复制
delete from report 
  where id not in (Select id 
                    from (SELECT * FROM report 
                          ORDER BY success desc) t 
                    group by  t.a_id, t.b_id)

现在对报告进行选择:

代码语言:javascript
复制
ID  A_ID    B_ID    SUCCESS
1   34       43     1
2   34       84     1
4   65       43     1
5   65       84     1
6   93       23     0

当不提供聚合函数时,可以检查group子句如何工作的文档:

在使用此功能时,每个组中的所有行都应该对组中按部分省略的列具有相同的值。服务器可以自由地从组返回任何值,因此除非所有值相同,否则结果是不确定的。

因此,只需在组by之前按'success执行订单,就可以使用success = 1获得第一个重复行。

票数 4
EN

Stack Overflow用户

发布于 2014-09-07 08:14:50

这个怎么样:

代码语言:javascript
复制
CREATE TABLE new_table 
  AS (SELECT * FROM old_table WHERE 1 AND success = 1 GROUP BY a_id,b_id);
DROP TABLE old_table;
RENAME TABLE new_table TO old_table;

此方法将创建一个具有临时名称的新表,并从旧表复制所有已销毁的行,这些行成功=1。然后删除旧表,并将新表重命名为旧表的名称。

如果我正确理解你的问题,这可能是最简单的解决办法。(虽然我不知道它是否真的有效)

票数 1
EN

Stack Overflow用户

发布于 2014-09-07 08:15:02

这应该是可行的:

如果像pl/sql这样的过程编程对您来说是可用的,那么它就相当简单。另一方面,如果您正在寻找一个干净的SQL解决方案,那么它可能是可能的,但并不是非常“好”。下面是pl/sql中的一个示例:

代码语言:javascript
复制
begin
  for x in ( select a_id, b_id
             from   table
             having count(*) > 1
             group  by a_id, b_id )
  loop
    for y in ( select *
               from   table
               where  a_id = x.a_id
               and    b_id = x.b_id
               order  by success desc )
    loop
      delete from table
      where  a_id = y.a_id
      and    b_id = y.b_id
      and    id != x.id;
      exit; // Only do the first row
    end loop;
  end loop;
end;

这就是我们的想法:对于a_id和b_id的每个重复组合,选择所有排序的实例,以便使用success=1的任何实例都是优先的。删除所有的组合,但第一个-是成功的,如果有的话。

或者也许:

代码语言:javascript
复制
declare
  l_a_id integer := -1;
  l_b_id integer := -1;
begin
  for x in ( select *
             from   table
             order  by a_id, b_id, success desc )
  loop
    if  x.a_id = l_a_id and x.b_id = l_b_id
    then
      delete from table where  id = x.id;
    end if;
    l_a_id := x.a_id;
    l_b_id := x.b_id;
  end loop;
end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25708124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档