如何在SQL(MSSQL)中逐行提交/执行删除

时间:2011-10-24 11:44:33

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

我有一个简单的表,但有一个很长的表(几百万或几行)。 该表包含许多我需要删除的配对行。 行数据不明显! 有单行(没有成对的行) 表对由连接到第3列的两列中的交叉信息定义。 我想每个数据标识符只有一行。 因此,我需要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子句将在要删除的每行测试中输出更短的列表。

我该怎么做?

1 个答案:

答案 0 :(得分: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