我们假设我们有以下表结构和值:
FooTable:
foo1 foo2 timestamp
1 1 1
2 2 1
2 1 2
目前桌面上没有主键约束。
问题:
在Oracle中,将foo1作为表的主键的最佳方法是什么?假设:
因此,这是查询后所需的表结构:
FooTable:
foo1(pk) foo2 timestamp
1 1 1
2 1 2
注意:主要问题是删除旧的重复行。完成此操作后,可以使用以下查询来设置主键,而不必担心重复:
alter table FooTable modify foo1 primary key;
答案 0 :(得分:3)
请记住,您在此处销毁数据。确保您有良好的数据库备份。
我不与Oracle合作,但我认为这很通用。我不知道Oracle是否允许在DELETE子句中使用表别名,因此您可能需要对其进行调整:
DELETE FT1
FROM FooTable FT1
WHERE EXISTS (
SELECT *
FROM FooTable FT2
WHERE
FT2.foo1 = FT1.foo1 AND
FT2.timestamp > FT1.timestamp
)
答案 1 :(得分:1)
如果foo1和timestamp的组合是唯一的,您可以创建一个复合键,然后创建一个只显示最大时间戳的视图。
这样可以保存您的数据。
答案 2 :(得分:-1)
DELETE FROM foo_table WHERE EXISTS
(
WITH q0 AS (SELECT foo1 AS f, timestamp AS ts, row_number() AS rn
FROM foo_table OVER (PARTITION BY foo1 ORDER by timestamp DESC) )
SELECT 1 FROM q0 WHERE q0.f=foo1 AND q0.timestamp=ts AND rn>1
);
其他一些版本的SQL允许相关子查询使用JOIN
样式。