SQL删除低计数

时间:2009-09-19 21:23:56

标签: sql mysql

我有一张包含这些数据的表格:

Id     Qty  
--     ---  
A       1  
A       2  
A       3  
B       112  
B       125  
B       109  

但我应该只为每个id设置最大值。 A的最大值为3,B的最大值为125.如何隔离(和删除)其他值?

决赛桌应如下所示:

Id     Qty  
--     ---   
A       3  
B       125  

运行MySQL 4.1

5 个答案:

答案 0 :(得分:2)

等等哦。有一个更简单的解决方案: 我将选择所有最大值(按ID分组),导出数据,刷新表,仅重新导入最大值。

CREATE TABLE tabletemp LIKE table;  
INSERT INTO tabletemp SELECT id,MAX(qty) FROM table GROUP BY id;  
DROP TABLE table;
RENAME TABLE tabletemp TO table; 

感谢所有人!

答案 1 :(得分:1)

在SQL Server中尝试:

delete from tbl o
left outer join 
(Select max(qty) anz , id
from tbl i
group by i.id) k on o.id = k.id and k.anz = o.qty
where k.id is null

MySQL的修订版2 ...任何人都可以查看这个吗?:

delete from tbl o
where concat(id,qty) not in 
    (select concat(id,anz) from (Select max(qty) anz , id
    from tbl i
    group by i.id)) 

说明:

由于我不应该使用连接(请参阅关于连接上的MySQL支持和删除/更新/插入的注释),我将子查询移动到IN(a,b,c)子句中。

在In子句中,我可以使用子查询,但该查询只允许返回一个字段。所以为了过滤所有不是最大的元素,我需要将两个字段连成一个,所以我可以在in子句中返回它。所以基本上我在IN内的查询只返回最大的ID + QTY。要将它与主表进行比较,我还需要在外部进行连接,因此两个字段的数据都匹配。

基本上,In子句包含: ( “A3”, “B125”)

免责声明:以上查询是“邪恶的!”因为它在字段上使用函数(concat)来进行比较。这将导致这些字段上的任何索引变得几乎无用。您永远不应该以定期运行的方式制定查询。我只想尝试弯曲它以便它适用于mysql。

这个“坏结构”的例子: (从过去2周内获取所有o) 从订单日+ 14的订单中选择...现在()

你应该总是这样做: 从订单日的订单中选择...>现在() - 14

差异很微妙:版本2只需要进行一次数学计算,并且能够使用索引,版本1必须对订单表中的每一行进行数学运算。您可以忘记索引使用...

答案 2 :(得分:0)

我试试这个:

delete from T
where exists (
  select * from T as T2
  where T2.Id = T.Id
  and T2.Qty > T.Qty
);

对于那些将来可能会遇到类似问题的人,有一天可能会支持这个问题(现在是SQL Server 2005及更高版本)

它不需要连接,如果表具有依赖关系,它优于使用临时表

with Tranked(Id,Qty,rk) as (
  select
    Id, Qty,
    rank() over (
      partition by Id
      order by Qty desc
    )
  from T
)
  delete from Tranked
  where rk > 1;

答案 3 :(得分:0)

你必须通过另一个表(除了其他一些使得单个删除语句在mysql中完全不可能的事情,你不能从表中删除并在子查询中使用相同的表)。

BEGIN;
create temporary table tmp_del select id,max(qty) as qty from the_tbl;
delete the_tbl from the_tbl,tmp_del where 
  the_tbl.id=tmp_del.id and the_tbl.qty=tmp_del.qty;
drop table tmp_del;
END;

答案 4 :(得分:-1)

MySQL 4.0及更高版本支持DELETE的简单多表语法:

DELETE t1 FROM MyTable t1 JOIN MyTable t2 ON t1.id = t2.id AND t1.qty < t2.qty;

这会生成具有给定id的每一行与具有相同id的所有其他行的连接,并且仅删除每个配对中具有较小qty的行。完成所有操作后,每个qtyid最大的行不会被删除。

如果您只有一行具有给定的ID,它仍然有效,因为单行自然是具有最大值的行。


FWIW,我刚刚在MacBook Pro 2.40GHz上使用MySQL 5.0.75尝试了我的解决方案。我插入了100万行合成数据,每个“组”包含不同的行数:

  • id个2行在26.78秒内完成。
  • id个5行在43.18秒内完成。
  • id 10行,1分钟内完成3.77秒。
  • id 100行,在6分钟内完成46.60秒
  • 每个id 1000行未在我终止之前完成。