每个唯一元组组合最多删除一条记录

时间:2011-08-25 22:50:47

标签: sql database tsql sql-server-2000

我想删除以下delete语句中每个唯一(columnA,columnB)-tuple的最多一条记录:

DELETE FROM tableA
WHERE columnA IN 
    (
    --some subqueryA
    )
AND columnB IN
    (
    --some subqueryB
    )

这是如何实现的?请仅考虑那些在使用MSS 2000时有效的语句(即T-SQL 2000语法)。我可以通过迭代一个temptable来做到这一点,但我想只使用集合来编写它。

示例:

subqueryA returns 1
subqueryB returns 2,3

如果原始表包含 (columnA,columnB,columnC)

5,2,5
1,2,34
1,2,45
1,3,86

然后

1,2,34
1,3,86 

应该删除。每个唯一(columnA,columnB)-tuple在tableA中最多出现两次,每次运行我的SQL语句时,我想删除这些唯一组合中的一个 - 从不两次。

如果给定唯一(columnA,columnB)-tuple有一条记录, 删除它。

如果给定唯一的两个记录(columnA, columnB)-tuple,只删除其中一个。

Delete tabA
from  TableA tabA 
Where tabA.columnC in (
      select  max(tabAA.columnC)  from TableA tabAA
      where tabAA.columnA in (1)
      and tabAA.columnB in (2,3)
      group by tabAA.columnA,tabAA.columnB
)

1 个答案:

答案 0 :(得分:1)

您是否经常使用这个,无论您是否使用临时表都很重要?也许您应该考虑在表中添加约束,这样您只需要执行一次...

尽管如此,老实说,为SQL Server 2000执行此操作的最佳方法可能是使用#temp表,因为您已经在做了。如果你试图删除每个欺骗中的一个,那么你可以做类似的事情:

  • 将不同的行插入单独的表格
  • 删除旧表中的所有行
  • 将不同的行移回原始表格

我还做了一些事情,比如将不同的行复制到新表中,删除旧表,然后重命名新表。

但这听起来不像是目标。你能用#temp表显示你目前使用的代码吗?我试图想象你是如何识别要保留的行,并且可能会看到现有代码会触发某些内容。

编辑 - 现在有了更好理解的要求,我可以提出以下查询。请先在表格的副本上进行测试!

DELETE a 
FROM dbo.TableA AS a
INNER JOIN 
(
   SELECT columnA, columnB, columnC = MIN(columnC) 
      FROM dbo.TableA
      WHERE columnA IN
      (
        -- some subqueryA
        SELECT 1
      )
      AND columnB IN 
      (
        -- some subqueryB
        SELECT 2 UNION SELECT 3
      )
      GROUP BY columnA, columnB
) AS x
ON  a.columnA = x.columnA
AND a.columnB = x.columnB
AND a.columnC = x.columnC;

请注意,这并不能确认只有一行或两行与columnA和columnB上的分组匹配。另请注意,如果运行两次,它将删除仍与子查询匹配的剩余行!