我的表中有重复的行,我想以最有效的方式删除重复的行,因为表很大.经过一些研究,我提出了这个问题:

WITH TempEmp AS
(
SELECT name, ROW_NUMBER() OVER(PARTITION by name, address, zipcode ORDER BY name) AS duplicateRecCount
FROM mytable
)
-- Now Delete Duplicate Records
DELETE FROM TempEmp
WHERE duplicateRecCount > 1;

但它只在SQL中有效,在Netezza中不起作用.似乎它不喜欢WITH条款之后的DELETE

推荐答案

我喜欢@erwin brandstetter的解决方案,但想展示一个包含USING关键字的解决方案:

DELETE   FROM table_with_dups T1
  USING       table_with_dups T2
WHERE  T1.ctid    < T2.ctid       -- delete the "older" ones
  AND  T1.name    = T2.name       -- list columns that define duplicates
  AND  T1.address = T2.address
  AND  T1.zipcode = T2.zipcode;

如果要在删除记录之前查看记录,只需将DELETE替换为SELECT *,将USING替换为逗号,即可.

SELECT * FROM table_with_dups T1
  ,           table_with_dups T2
WHERE  T1.ctid    < T2.ctid       -- select the "older" ones
  AND  T1.name    = T2.name       -- list columns that define duplicates
  AND  T1.address = T2.address
  AND  T1.zipcode = T2.zipcode;

更新:为了提高速度,我在这里测试了一些不同的解决方案.如果您不希望有太多重复项,那么这个解决方案的性能要比那些有NOT IN (...)子句的解决方案好得多,因为它们会在子查询中生成很多行.

如果您将查询重写为使用IN (...),那么它的性能与这里介绍的解决方案类似,但SQL代码变得不那么简洁.

更新2:如果你在其中一个关键列中有NULL个值(你真的不应该这么做),那么你可以在该列的条件中使用COALESCE(),例如.

  AND COALESCE(T1.col_with_nulls, '[NULL]') = COALESCE(T2.col_with_nulls, '[NULL]')

Sql相关问答推荐

如何根据SQL中的列条件获取下一个时间戳?

SQL计数所有值在联接范围内的行

SQL查询每个客户的最新条目

对任何(数组)使用LIKE?

Ffltter&;Dart SQL Lite包:是否可以在一个查询中执行多条更新语句(每次执行不同的WHERE参数)

正在编写查询.我需要将订阅的时间段分为第一个订阅中包含的另一个订阅之前和之后的时间段

如果另一个表中不存在值列,则插入失败

如何在Postgres中为单值输入多行?

在子窗口SQL Presto中使用特定条件执行值计数

在VB.NET中如何在MS Access数据库中创建SQL项目历史库存卡

为什么左联接结果在MS Access数据库中不匹配

在 PostgreSQL 中生成时间序列查询

聚合内部的条件在哪里?

如何在 golang squirrel lib 中添加 postgreSQL 的distinct on

如何修复初学者 SQL INNER JOIN 查询错误

如何在sparksql查询中使用日期值?

COBOL\DB2作业(job)需要帮助?快来获取专业指导!

如何对 SQL 表中的连续时间戳进行分组?

如何将多行的查询结果合并为一行

SQL 查询以填充单个列中的所有值