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

发布于 2024-12-01 23:59:54 字数 951 浏览 0 评论 0原文

我想在以下删除语句中为每个唯一的(columnA,columnB)元组最多删除一条记录:

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

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

示例:

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)元组在 tableA 中最多出现两次,每次运行 SQL 语句时,我最多想删除这些唯一组合中的一个 - 永远不会两个。

如果给定的唯一(columnA,columnB)元组有一条记录, 删除它。

如果给定的唯一记录有两条记录(columnA, columnB)-元组,仅删除其中一个。

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
)

I want to delete at most one record for each unique (columnA, columnB)-tuple in my following delete statement:

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

How is this accomplished? Please only consider those statements that work when used against MSS 2000 (i.e., T-SQL 2000 syntax). I can do it with iterating through a temptable but I want to write it using only sets.

Example:

subqueryA returns 1
subqueryB returns 2,3

If the original table contained
(columnA, columnB, columnC)

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

Then

1,2,34
1,3,86 

should be deleted. Each unique (columnA, columnB)-tuple will appear at most twice in tableA and each time I run my SQL statement I want to delete at most one of these unique combinations - never two.

If there is one record for a given unique (columnA, columnB)-tuple,
delete it.

If there are two records for a given unique (columnA,
columnB)-tuple, delete only one of them.

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
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情丝乱 2024-12-08 23:59:54

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

也就是说,老实说,对于 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 上的分组匹配。另请注意,如果运行两次,它将删除仍与子查询匹配的剩余行!

How often are you going to be running this that it matters whether you use temp tables or not? Maybe you should consider adding constraints to the table so you only have to do this once...

That said, in all honesty, the best way to do this for SQL Server 2000 is probably to use the #temp table as you're already doing. If you were trying to delete all but one of each dupe, then you could do something like:

  • insert the distinct rows into a separate table
  • delete all the rows from the old table
  • move the distinct rows back into the original table

I've also done things like copy the distinct rows into a new table, drop the old table, and rename the new table.

But this doesn't sound like the goal. Can you show the code you're currently using with the #temp table? I'm trying to envision how you're identifying the rows to keep, and maybe seeing your existing code will trigger something.

EDIT - now with better understood requirements, I can propose the following query. Please test it on a copy of the table first!

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;

Note that this doesn't confirm that there are exactly one or two rows that match the grouping on columnA and columnB. Also note that if you run this twice it will delete the remaining row that still matches the subquery!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文