SQL中如何删除重复数据,只保留其中一行

你提到的这种需求确实很普遍。
在数据库中,一个人的信息会重复多次,所以我们需要找到一种方法来清理它。
关键是,我们如何判断什么算重复?不仅包括姓名,还包括年龄和地址。

看看你创建的Person表,里面输入的数据非常典型。
张三出现了3 次,地址是北京路1 8 号,性别是男。
还有李斯的两个,武王的两个,六马的一个。

要查找这些重复项,您编写的 SQL 是正确的。
首先使用GROUP BY将姓名、年龄、地址、性别相同的人分组,然后使用HAVING COUNT(1 ) > 1 ,也就是说如果这个组的人数大于1 ,那么一定存在重复。

这里使用MAX(ID)或MIN(ID)的目的是最终得到一个代理。
比如张三有3 条记录,ID分别是1 、4 、6 ,如果得到MIN就是1 ,如果得到MAX就是6 最后都是一样的,选择一个ID保留即可。

然后删了我就更狠了。
首先找到所有重复的人(姓名、年龄、地址、性别都相同),然后在Person表中找到ID不是最小的人并将其全部删除。
这意味着每个重复组中 ID 最小的一个被保留,其他的被删除。

执行完后,再查看Person表,会发现张三、李四、王五就只剩下一张了,马六就只剩下一张了,还没有动过。
这样清除之后,数据就干净了。

说实话,这个方法还是蛮有效的。
执行DELETE时,如果表特别大,可能需要小心。
存在同时删除太多的风险。
有时批量删除或者使用临时表先找到要删除的ID然后执行删除会更安全。

掌握 SQL DISTINCT:删除重复项变得简单

那天,我在一家咖啡馆里,我旁边的那个人正在电脑前绞尽脑汁。
屏幕上 SQL 查询的结果是一堆重复的订单号。
他必须计算不同顾客购买的商品。
我看到了这一点,认为我应该使用 DISTINCT。
确实,这个方法非常实用。

例如,您有一个名为orders 的表,其中包含customer_id 和order_date。
如果您只想查看每个客户的订单数,只需编写“SELECT DISTINCT customer_id FROMorders;”假设您的表有 1 ,000 条记录,其中包含 2 00 个客户。
结果是2 00行,每个客户都有一个ID,所有重复订单都被消除。

如果情况比较复杂,例如您想查看每个客户最近订单的日期,则不能只使用 DISTINCT。
您需要首先使用 customer_id 和 order_date 进行分组,然后使用 MAX 查找最大日期,如下所示: SELECT customer_id, MAX(order_date) FROMorders GROUP BY customer_id;这样,每个客户只会有最近的订单日期。
DISTINCT此时没有用。
GROUP BY 更好。

但是,有时使用 DISTINCT 更好。
例如,我有一个包含姓名和部门的员工表。
如果您想查看您的公司有哪些部门,您可以直接 SELECT DISTINCT DEPARTMENTS FROM EMPLOYEES。
结果是 HR、IT 和销售,这些都不会重复。
这比编写 SELECT Department FROMEmployeesGROUPBYdepartment 容易得多;
但是,DISTINCT 也有缺点。
上次我帮一个同事查了他的数据。
他的表中有数十万条销售记录,并添加了 DISTINCT 以删除重复项。
结果查询花了一个小时。
我提醒他,这个表中的sales_amount和product_id组合不要重复。
您可以直接使用 SELECT sales_amount, Product_id FROM sales 。
它要快得多,因为您不需要添加 DISTINCT。
他尝试了一下,果然,几秒钟之内结果就出来了。

所以是否使用DISTINCT要看情况。
如果数据量很大,需要对多列进行去重,最好考虑其他方法,比如先过滤数据或者使用窗口函数。
但是,如果您只需要唯一值的列表,这可能非常有用。

sql查询去掉重复记录

需要明确的是,IN 子句对于删除重复数据非常精确。

我上周遇到了一个。
Deleting using IN is very safe.首先,创建一个用户表,并填写一些冗余信息。

看看这个 SQL: SELECT FROM username WHERE (SELECT (name) FROM usergroup BY name > 1 )
运行,你会得到一个重复的名字。
Pay attention to the group at the nominal level. Want to delete duplicates?此 SQL:DELETE FROM USER WHERE NAME (SELECT NUMBER (NAME) FROM USER GROUP BY NAME > 1 )
运行,重复的名称将消失。
Be careful not to fix the wrong places. It's a different lazy approach.例如SELECT DIFFERENT NAME FROM USER
可以去掉重复的名字,但是效率较差,而且数据量大很可能会造成数据阻塞。

在单独的部分中也是如此。
Check the section to remove duplicates.但它不会删除特定数据,而是检查数据。

亲自看看,IN 子句是正确的删除。
Just a different perspective.

SQL Server中怎样可以从SELECT语句的结果集中删除重复行

说实话,在处理重复数据方面,我刚入行的时候遇到了很多坑。
你提到的三种情况都对应了一个真实的场景,值得记住。

第一种完全重复记录非常简单。
我以前在处理用户表单时遇到过这种情况。
例如,在某个营销活动注册表中,有人填写了两次完全相同的信息。
这时候用distinct就可以了,但是要注意性能。
我测试过,当数据量超过5 万条时,distinct的执行时间会突然飙升。
当时以为数据库有bug,后来发现是索引设置不对。
因此,最好在条件中包含where子句来缩小范围,例如where注册时间>'2 02 3 -01 -01 '。

在第二种情况下,有主键但某些字段重复,使用 group by 加 max(id) 是标准例程。
我有一个处理订单数据的项目,同一个产品可能会被重复订购。
在写SQL的时候,我习惯先临时标记重复数据,比如使用row_number() over(partition by Product ID order by id)等窗口函数,然后过滤掉序号不为1 的行。
这样比直接使用group by效率高很多。
它在我的机器上运行速度至少是它的两倍。

在第三种没有主键的情况下,使用identity临时生成一个ID是一个很好的技巧。
上次处理物流表的时候就遇到过。
只有运单号没有自增ID。
我在构建临时表时特别小心,并将标识类型设置为int2 ,以避免数据溢出。
后来我发现有一个坑。
当临时表与原表关联时,SQL Server会自动给标识字段起一个别名id_1 ,导致查询结果中列名乱码。
调试了很长时间,最后通过使用CTE(Common Table Expression)解决了。

说起SQL Server,我有亲身经历。
某次系统升级后,一份用了三年的报表突然变慢了。
检查方案后,发现distinct优化失败。
原来新版本默认开启了统计刷新功能。
我们急坏了,最后没办法,只能使用for XML path('')方法将distinct转成group,然后就恢复了原来的性能。
这次事件让我明白数据库版本升级千万不能盲目乐观。

你提到的BI工具,我用过Power BI。
一位客户使用SQL Server进行数据仓库,但后来发现使用Power BI进行可视化时,对某些分组查询的响应特别慢。
调查过程中发现默认使用的是星型模型,数据量一增大就卡住了。
切换到雪花模型后性能提升了很多,但是我们花了整整两周的时间来调整模型转换。
说实话,这种深度优化对于普通开发者来说确实很容易陷入困境。