架构
因此,您有一个包含 版本化 对象的表,其中包含与该对象关联的更改记录以及一些详细信息和日期。
现在你要选择
- 每个对象的第一次更改
- 最早的(在此对象更改的 GROUP 内)
- 在
DATE 列类型上使用MIN 函数
这个最旧的应该被保留/保留并留下。应删除所有其他对象更改版本。
解决
A.分两步选择每个对象的第一个/最旧的更改。
- 选择每个对象的 MIN(日期):
SELECT Object_ID, COUNT(Object_ID) AS Count_Changes, MIN(Date_of_Change) AS First_Change
FROM table
GROUP BY Object_ID
结果集包含每个对象的 total 更改计数和第一次更改的日期。
- 在
JOIN 中使用subquery 之前的结果选择第一个更改:
SELECT *
FROM table t
-- join with a table-subquery having only 2 columns to correlate
JOIN (
SELECT Object_ID, MIN(Date_of_Change) AS First_Change
FROM table
WHERE Current_Step is NULL and Change = 'change'
GROUP BY Object_ID
) m ON t.Object_ID = m.Object_ID AND t.Date_of_Change = m.First_Change
WHERE Current_Step is NULL and Change = 'change'
这是要保留而不是删除的行。每个对象的第一次更改应该保留而不是清理。
B.现在我们可以反转 JOIN 条件来获取我们想要删除/清理的所有行:
- 更改日期比较
) m ON t.Object_ID = m.Object_ID AND t.Date_of_Change = m.First_Change
不等于:
) m ON t.Object_ID = m.Object_ID AND t.Date_of_Change <> m.First_Change
- 首先运行干选,至少在删除之前获得计数。
SELECT COUNT(Object_ID) AS records_to_remove
FROM table t
-- join with a table-subquery having only 2 columns to correlate
JOIN (
SELECT Object_ID, MIN(Date_of_Change) AS First_Change
FROM table
WHERE Current_Step is NULL and Change = 'change'
GROUP BY Object_ID
) m ON t.Object_ID = m.Object_ID AND t.Date_of_Change <> m.First_Change
WHERE Current_Step is NULL and Change = 'change'
- 使用 JOIN 准备 DELETE 语句(如果 DBMS 支持):
DELETE FROM table t
JOIN (
SELECT Object_ID, MIN(Date_of_Change) AS First_Change
FROM table
WHERE Current_Step is NULL and Change = 'change'
GROUP BY Object_ID
) m ON t.Object_ID = m.Object_ID AND t.Date_of_Change <> m.First_Change
WHERE t.Current_Step is NULL AND t.Change = 'change'
替代 JOIN 在其他 DBMS 上尝试 USING
某些 DBMS 不支持在 DELETE 语句中加入 JOIN,但可以使用 USING 等替代方法:
DELETE FROM table t
USING (
SELECT Object_ID, MIN(Date_of_Change) AS First_Change
FROM table t2
WHERE t2.Current_Step is NULL AND t2.Change = 'change'
) AS m
WHERE ...
AND t.Object_ID = m.Object_ID AND t.Date_of_Change <> m.First_Change