【问题标题】:How do I commit/execute deletion row by row in SQL (MSSQL)如何在 SQL (MSSQL) 中逐行提交/执行删除
【发布时间】:2011-12-14 01:49:32
【问题描述】:

我有一张简单的表格,但表格很长(几百万或几行)。 该表包含许多我需要删除的配对行。 行数据不明显! 有单行(没有成对的行) 表对由连接到第三列的两列中的交叉信息定义。 我希望每个数据标识符只有一行。 因此,我需要 myTable 在满足条件的情况下立即收缩。 我试过了:

myIndexColumn = Column1 + Column2 + Column3
myReversedIndexColumn = Column2 + Column1 + Column3

CREATE NONCLUSTERED INDEX myIndex1 ON myDB.dbo.myTable (
  myIndexColumn ASC
)
CREATE NONCLUSTERED INDEX myIndex2 ON myDB.dbo.myTable (
  myReversedIndexColumn ASC
)

DELETE FROM myDB.dbo.myTable
WHERE myIndexColumn in (SELECT myReversedIndex FROM myDB.dbo.myTable)

问题是两个配对数据都被删除而不是留下一行数据。

显然,这是因为DELETE 仅在运行整个事务后才提交更改。

如果我可以说服 MS SQL 2008 R2 Express 版本在满足条件时提交 DELETE,那么 SELECT 子句将在要删除的每一行测试中输出一个较短的列表。

我该怎么做?

【问题讨论】:

  • 据我所知,只有那些 myReversedIndexColumn = myIndexColumn 的行应该被删除,这是 Column1 = Column2 的地方。你是说 所有 成对的行都被删除了
  • 我刚刚仔细检查,它正在删除所有配对数据(大部分表格)。发生这种情况是因为存在具有特定反向索引的行就足以删除一行。我要做的是有一个更新的(按操作 - 逐行)列表以供选择,以便决定成功删除。虽然一般情况是每行的索引不同,但有少数行的索引相等 (0.006%)。
  • 那么,你想去掉 0.006 的大小写吗?
  • 不,我需要这些行。我只想删除~一半的数据。只有每对行中的第二行。
  • 这是关于删除半重复的。忘记 column1=column2,我可以控制它。重复定义为好像有两行,其中 row1.column3=row2.column3 和 row1.column1=row2.column2 和 row2.column1=row1.column2 。在这种情况下如何删除 dup?

标签: sql sql-server commit execute sql-delete


【解决方案1】:

删除 column1 = column2 的情况

DELETE FROM myDB.dbo.myTable
WHERE myIndexColumn in (SELECT myReversedIndex FROM myDB.dbo.myTable)
  AND column1 <> column2

删除 column1 = column2

;with cte as
(
    select *,
        row_number() over (
                partition by Column1 + Column2 + Column3
                order by (SELECT 1)
                ) rn
    from yourtable
    where column1 = column2
)
delete cte where rn > 1

CTE 也可用于删除所有重复项

;with cte as
(
    select *,
        row_number() over (
                partition by 
                      CASE WHEN Column1 > Column2 THEN Column2 ELSE Column1 END + 
                      CASE WHEN Column1 > Column2 THEN Column1 ELSE Column2 END + 
                      Column3
                order by (SELECT 1)
                ) rn
    from yourtable
)
delete cte where rn > 1

【讨论】:

  • 谢谢,但我找不到上述任何有用的东西。是的,它是关于删除半重复的。忘记 column1=column2,我可以控制它。重复定义为好像有两行,其中 row1.column3=row2.column3 和 row1.column1=row2.column2 和 row2.column1=row1.column2 。关于您的 dup remove 我仍然尝试运行它,但没有运气。
  • Column1 和 Column2 包含连续两年班级中孩子的姓名。两个列表包含几乎相同的数据(一个用于第 1 年,另一个用于第 2 年),因为班上的孩子相同(一些新的一些被丢弃)。 Column1=column2 仅当孩子独自做功课时,这非常罕见且不重要(默认情况下,班级人数为偶数,但有时会生病或休假)。
  • 所有孩子在不同场合与所有(大多数)孩子分开完成每项任务。 (我不介意学习曲线,有时它是关于匹配的)每一行代表成就(第 4 列)和更多的个人数据(第 5-8 列为孩子第 1 列,第 9-12 列为第 2 列中的孩子)是特定任务(第 3 列)
  • column1 + column2 做任务 column3 与 column2 + column1 做任务 column3 是同一对,那么 column4 中的数据是相同的,因此是多余的,应该删除其中的一行,但不是其他。就是这么简单,这正是我所需要的。
  • 尽管如此,我的问题更广泛:是否可以让 SQL 服务器在每行测试删除后在删除操作中更新表,就像每行之后的 GO 一样?如果可能的话,我的查询对我来说很好。例如,如果我可以将 GO inside 放在 DELETE 中以在每一行之后实际提交删除,这对我来说还有很多其他用途。
猜你喜欢
  • 1970-01-01
  • 2012-09-17
  • 2015-03-15
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多