Sql 如何仅删除冗余数据?

Sql 如何仅删除冗余数据?,sql,database,database-design,primary-key,informix,Sql,Database,Database Design,Primary Key,Informix,如果我有这样的桌子: ID FROM_DATE TO_DATE 18177 2016-04-20 00:00 2016-04-20 00:00 18177 2016-04-20 00:00 2016-04-20 00:00 18177 2016-04-23 00:00 2016-04-23 00:00 18177 2016-04-23 00:00 2016-04-23 00:00 18177 2016-04-24 00:0

如果我有这样的桌子:

ID      FROM_DATE           TO_DATE
18177   2016-04-20 00:00    2016-04-20 00:00
18177   2016-04-20 00:00    2016-04-20 00:00
18177   2016-04-23 00:00    2016-04-23 00:00
18177   2016-04-23 00:00    2016-04-23 00:00
18177   2016-04-24 00:00    2016-04-24 00:00
18177   2016-04-24 00:00    2016-04-24 00:00
18177   2016-04-26 00:00    2016-04-26 00:00
18177   2016-04-26 00:00    2016-04-26 00:00
18177   2016-04-27 00:00    2016-04-27 00:00
18177   2016-04-27 00:00    2016-04-27 00:00
18177   2016-04-30 00:00    2016-04-30 00:00
18177   2016-04-30 00:00    2016-04-30 00:00
这个表没有键,我发现我自己需要设置由三列组成的主键,但我不能这样做,因为数据重复

如何删除冗余数据?例如,如果我有两条数据相同的记录,我只想保留一条记录

我希望这样的结果能够解决问题并设置密钥:

ID      FROM_DATE           TO_DATE
18177   2016-04-20 00:00    2016-04-20 00:00
18177   2016-04-23 00:00    2016-04-23 00:00
18177   2016-04-24 00:00    2016-04-24 00:00
18177   2016-04-26 00:00    2016-04-26 00:00
18177   2016-04-27 00:00    2016-04-27 00:00
18177   2016-04-30 00:00    2016-04-30 00:00
这行吗

delete from t
    where rowid not in (select min(rowid)
                        from t
                        group by id, from_date, to_date
                       );
默认情况下,Informix表有一个内置的rowid列。如果这个版本有效,您可以将子查询放入一个临时表中并使用它

另请注意:这样做通常更快:

select distinct id, from_date, to_date
from t
into temp temp_t;

truncate table t;

commit;  -- If there was a transaction active

insert into t(id, from_date, to_date)
    select id, from_date, to_date
    from temp_t;
这可能会更快,因为在进行大规模删除时需要考虑日志记录和锁定问题。

这样做有效吗

delete from t
    where rowid not in (select min(rowid)
                        from t
                        group by id, from_date, to_date
                       );
DELETE FROM Table_Name
WHERE ROWID NOT IN (SELECT MAX(ROWID) FROM Table_Name
                    GROUP BY Id,From_Date,To_Date
                   );
默认情况下,Informix表有一个内置的rowid列。如果这个版本有效,您可以将子查询放入一个临时表中并使用它

另请注意:这样做通常更快:

select distinct id, from_date, to_date
from t
into temp temp_t;

truncate table t;

commit;  -- If there was a transaction active

insert into t(id, from_date, to_date)
    select id, from_date, to_date
    from temp_t;
这可能会更快,因为在进行大规模删除时需要考虑日志记录和锁定

DELETE FROM Table_Name
WHERE ROWID NOT IN (SELECT MAX(ROWID) FROM Table_Name
                    GROUP BY Id,From_Date,To_Date
                   );
首先,它将执行内部查询,并根据Id创建不同的组,从\u Date&到\u Date。这样,所有重复记录都只属于同一组,然后通过只选择每个组中的最大rowid来过滤不同的记录。然后执行外部查询并删除重复记录

ROWID对于插入数据库的每个记录都是唯一的,即DBMS本身内部提供的记录

首先,它将执行内部查询,并根据Id创建不同的组,从\u Date&到\u Date。这样,所有重复记录都只属于同一组,然后通过只选择每个组中的最大rowid来过滤不同的记录。然后执行外部查询并删除重复记录


ROWID对于插入到数据库中的每个记录都是唯一的,即DBMS本身内部提供的记录。

创建一个复制表,插入到复制中,选择与Originatable不同的*。Rename@jarlh:我编辑问题了解以下内容:创建一个复制表,插入到复制中,选择与原始表格不同的*项。Rename@jarlh:我编辑问题了解一下这一点:我尝试先这样选择:选择*从t,其中rowid不在,选择minrowid从t按id分组,从_日期,到_日期;当我使用unique时,我得到的行数更少!!我有更多的专栏btw@anyname-donotcare和这些其他列的每一行都有不同的值?对于同一id,从_date到_date的其他列是否可能跨行不同?如果是这样,您将如何选择保留哪一行?@anyname donotcare您是否可以发布相关表的:完整架构;从t中选择计数*的结果;按id从t组中选择计数*的结果,从\u日期到\u日期;SELECT COUNT*FROM SELECT UNIQUE*FROM t的结果。现在它工作正常,我能知道如何在sql server中执行同样的操作吗?请尝试先这样选择:SELECT*FROM t,其中rowid不在,SELECT minrowid FROM t group by id,FROM_date,to_date;当我使用unique时,我得到的行数更少!!我有更多的专栏btw@anyname-donotcare和这些其他列的每一行都有不同的值?对于同一id,从_date到_date的其他列是否可能跨行不同?如果是这样,您将如何选择保留哪一行?@anyname donotcare您是否可以发布相关表的:完整架构;从t中选择计数*的结果;按id从t组中选择计数*的结果,从\u日期到\u日期;SELECT COUNT*FROM SELECT UNIQUE*FROM t的结果。现在它工作正常,我可以知道如何在sql server中执行同样的操作吗