mysql去重

mysql去重

原因:由于表是各地归集过来的,通过前置机数据交换,很多数据会重复。
目的:删除数据库某张表的重复数据

方法一(将查询出无重复的数据导入临时表,再将原表删除,再将临时表的数据导回原表) 适用于无主键,所有字段完全匹配,数据量小的情况:

DELIMITER //
CREATE PROCEDURE delete_rows(IN tablename VARCHAR(50))
BEGIN
SET @tablename = tablename;
SET @tmp_table = CONCAT('tmp_table_',@tablename);

SET @create_table = CONCAT('DROP TABLE IF EXISTS ',@tmp_table);
PREPARE create_table FROM @create_table;
EXECUTE create_table;

SET @create_table = CONCAT('CREATE TEMPORARY TABLE ',@tmp_table,' SELECT DISTINCT * from ',@tablename);
PREPARE create_table FROM @create_table;
EXECUTE create_table;

SET @create_table = CONCAT('TRUNCATE TABLE ',@tablename);
PREPARE create_table FROM @create_table;
EXECUTE create_table;

SET @create_table = CONCAT('INSERT INTO ',@tablename,' SELECT * from ',@tmp_table);
PREPARE create_table FROM @create_table;
EXECUTE create_table;
END//
DELIMITER ;

CALL delete_rows('表名');

方法二(给表加自增主键) 适用于根据某几个字段去重,有主键:

DELIMITER //
CREATE PROCEDURE delete_rows_1(IN tablename VARCHAR(50),IN fieldnames VARCHAR(100),IN autofield VARCHAR(50))
BEGIN
SET @tablename = tablename;
SET @fieldnames = fieldnames;
SET @autofield = autofield;

SET @create_table = CONCAT('DELETE FROM ', @tablename ,' WHERE ', @autofield ,' not in (SELECT id FROM (SELECT max(', @autofield ,') id FROM ', @tablename ,' GROUP BY ', @fieldnames ,') t)');
PREPARE create_table FROM @create_table;
EXECUTE create_table;
END//
DELIMITER ;

CALL delete_rows_1('表名', '字段1,字段2,字段3...', '主键字段');
posted @ 2018-01-22 11:07 jarjune 阅读( ...) 评论( ...) 编辑 收藏
### MySQL 方法及其实现 在 MySQL 数据库中,是一个常见需求,可以通过多种方式实现。以下是几种主要的方法及其具体实现: #### 使用 `DISTINCT` 关键字 `DISTINCT` 是一种简单而有效的方式,用于返回唯一的不同值组合。它可以直接应用于列或者多个列上以复项。 ```sql SELECT DISTINCT column_name FROM table_name; ``` 这种方法适用于简单的场景,当只需要获取某一列或多列中的不复记录时非常有用[^1]。 #### 利用 `GROUP BY` 子句 除了 `DISTINCT` 外,还可以使用 `GROUP BY` 来达到相同的效果。这种方式不仅可以复数据,还能配合聚合函数一起使用,比如计算每组的数量或其他统计数据。 ```sql SELECT column_name FROM table_name GROUP BY column_name; ``` 需要注意的是,在性能方面,对于大规模数据集来说,`GROUP BY` 的执行速度可能不如 `DISTINCT` 高效[^3]。 #### 应用窗口函数 `ROW_NUMBER()` 进行复杂 随着版本更新至8.0及以上之后,MySQL 开始支持窗口函数,这使得我们可以更加灵活地处理复杂的业务逻辑问题。例如下面的例子展示了如何利用 `ROW_NUMBER()` 函数标记每一行并保留第一条作为代表来进行更精细控制下的删除动作。 ```sql WITH CTE AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY duplicate_column ORDER BY some_ordering_field) as row_num FROM your_table ) DELETE FROM your_table WHERE id IN (SELECT id FROM CTE WHERE row_num > 1); ``` 此脚本首先创建了一个公共表达式(CTE),其中包含了原始表格加上额外的一列row_num表示该分区内按指定顺序排列后的序号;接着再基于这个结果集中找出那些不是第一个实例的所有行予以移除[^4]。 #### 统计不同维度上的数量 有时候我们不仅仅关心如何掉冗余的信息本身,还希望了解到底存在多少种独特的组合形式以及它们各自对应的频次分布情况等等附加信息,则可以采用如下所示的形式完成相应任务目标设定: ```sql SELECT SUM(c) total_count FROM( SELECT COUNT(DISTINCT col_a,col_b) c FROM tbl_x UNION ALL SELECT COUNT(DISTINCT col_c,col_d) c FROM tbl_y )AS subquery_alias ; ``` 上述代码片段演示了跨两个独立关系型结构之间分别实施差异化考量后再累加得到最终总数的过程[^5]。 ### 性能对比与适用场合分析 不同的手段各有优劣之处,实际应用过程中应根据具体情况选择最合适的方案: - 如果只是单纯想查看某几字段联合起来是否存在多条完全一致的情况那么优先考虑distinct; - 当涉及到进一步加工运算诸如求平均值之类的操作则推荐选用groupby; - 而针对一些特殊定制化的需求像只保存最新版之类的要求就不得不借助于高级特性如window function来满足预期效果了。 总之,理解这些技术背后的原理有助于开发者做出明智决策从而优化整体解决方案的质量水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值