试试这个:
DELETE t
OUTPUT deleted.*
FROM ItemTable t
JOIN (
SELECT DENSE_RANK() OVER (PARTITION BY ItemLabel ORDER BY lt.ItemID DESC, it.id) num
, it.Id
FROM ItemTable it
LEFT JOIN
LinkTable lt ON
lt.ItemId = it.id
) t2 ON t2.Id = t.Id
WHERE num > 1
SQL小提琴
尽管上述方法适用于您的情况,但我建议您使用更具可读性并且您将拥有更多控制权和更好概览的方法。这是一种多步骤方法,可以分析和测试每个步骤:
-- get ItemLabels of duplicate records
SELECT ItemLabel
INTO #Duplicate_ItemLabels
FROM ItemTable it
GROUP BY
it.ItemLabel
HAVING COUNT(*) > 1
-- get ItemLabels of duplicate records that have at least one record related to LinkTable
SELECT *
INTO #Duplicate_ItemLabels_Related_To_LinkTable
FROM #Duplicate_ItemLabels d1
WHERE EXISTS
(
SELECT *
FROM ItemTable it
JOIN Linktable lt ON
lt.ItemID = it.ID
WHERE it.ItemLabel = d1.ItemLabel
)
-- get ItemLabels of duplicate records that don't have any records related to LinkTable
SELECT ItemLabel
INTO #Duplicate_ItemLabels_NOT_Related_To_LinkTable
FROM #Duplicate_ItemLabels
EXCEPT
SELECT ItemLabel
FROM #Duplicate_ItemLabels_Related_To_LinkTable
-- delete unwanted records for ItemLabels that have records related to linkTable
DELETE it
OUTPUT deleted.*
FROM ItemTable it
JOIN #Duplicate_ItemLabels_Related_To_LinkTable dup ON
dup.ItemLabel = it.ItemLabel
WHERE NOT EXISTS
(
SELECT *
FROM Linktable lt
WHERE lt.ItemID = it.ID
)
-- delete unwanted records for ItemLabels that don't have any records related to linkTable
DELETE it
OUTPUT deleted.*
FROM ItemTable it
JOIN #Duplicate_ItemLabels_NOT_Related_To_LinkTable dup ON
dup.ItemLabel = it.ItemLabel
JOIN
(
-- records deleted will be all those that have ID greater than the smallest ID for this ItemLabel
SELECT ItemLabel
, MIN(ID) ID
FROM ItemTable dup
GROUP BY
dup.ItemLabel
) gr ON
gr.ID < it.ID
AND gr.ItemLabel = dup.ItemLabel
-- if after these DELETEs there are still duplicate records, it
-- means that there are records for same ItemLabel with
-- different ID and all of them are related to LinkTable
您可以轻松地对其进行修改、测试结果并操作将删除哪些记录。我创建了一个SQL Fiddle,我在其中放置了不同的数据样本,以便您可以看到它是如何处理的。
为了对第二种方法的数据进行采样,我还添加了记录,ItemTable
其中您有相同但ItemLabel
不同ID
的记录有多个相关LinkTable
(没有一个被任意删除)。