【发布时间】:2019-09-28 02:06:06
【问题描述】:
DataTable 表的结构如下:每一列的数据类型为 int,RowID 是一个标识列和主键。 LinkID 是一个外键,链接到另一个表的行。
RowID LinkID Order Data DataSpecifier
1 120 1 1 1
2 120 2 1 3
3 120 3 1 10
4 120 4 1 13
5 120 5 1 10
6 120 6 1 13
7 371 1 6 2
8 371 2 3 5
9 371 3 8 1
10 371 4 10 1
11 371 5 7 2
12 371 6 3 3
13 371 7 7 2
14 371 8 17 4
.................................
.................................
我正在尝试通过以下方式更改每个 LinkID 批次的查询:
- 使用相同的
LinkID获取每一行(例如,这里的第一批是前 6 行) - 按
Order列排序 - 将
Data和DataSpecifier列视为一个比较单元(可以将它们视为一列,称为dataunit): - 从
Order=1开始保留尽可能多的行,直到dataunit在批处理中出现多次为止 - 保留最后一行,但删除具有相同
LinkID和更大Order值的其余行
所以对于LinkID 120:
- 按
Order列对批次进行排序(此处已排序,但仍应这样做) - 从顶部开始查看(此处为
Order=1),只要您没有看到批处理中出现超过 1 次的值即可 - 在第一个重复的
Order=3处停止(dataunit1 10也在Order5)。 - 删除所有有
LinkID=120 AND Order>=4
在对LinkID371(以及表中的所有其他LinkID)进行类似处理后,处理后的表将如下所示:
RowID LinkID Order Data DataSpecifier
1 120 1 1 1
2 120 2 1 3
3 120 3 1 10
7 371 1 6 2
8 371 2 3 5
9 371 3 8 1
10 371 4 10 1
11 371 5 7 2
.................................
.................................
我从来没有做过这么复杂的 SQL 查询。我知道查询必须是这样的:
DELETE FROM DataTable
WHERE RowID IN (SELECT RowID
FROM DataTable
WHERE -- ?
GROUP BY LinkID
HAVING COUNT(*) > 1 -- ?
ORDER BY [Order]);
但我似乎无法解决这个问题并正确查询。我最好在纯 SQL 中执行此操作,使用一个可执行(和可重用)查询。
我在这里问了一个非常相似的问题:How to remove rest of the rows with the same ID starting from the first duplicate?
但由于我意识到问题中的原始过滤逻辑实际上并不是我所需要的,并且该问题已经得到正确回答,所以我不得不提出这个新问题。
【问题讨论】:
-
我认为您可以使用此处提供的答案:stackoverflow.com/questions/42133711/…
标签: sql sql-server tsql duplicates sql-delete