首页 > 解决方案 > 根据组中是否存在值从重复项中选择两条记录

问题描述

我有一张表,其中一列中有重复项。我需要保留其中一条重复记录并删除另一条。但是在我删除一个之前,我必须将与要删除的那个相关联的所有其他依赖表记录指向我要保留的那个。另外,如果可能的话,我想检查一个条件以选择要保留和删除的条件,如果该条件不满足,则保留MIN()并删除MAX().

例如我有这张表叫工人

在此处输入图像描述

我想按workerID列分组,然后检查组内是否有 2 条记录具有isActive = 'No'. 如果是,请抓住该记录的工作人员并将其标记为ToKeep。如果组中的两条记录的isActive均为 Yes,则将其MIN(worker)设为 ToKeep 和MAX(worker)ToDelete。

因此,基于此示例的结果将是这样的

在此处输入图像描述

是否可以编写查询来做到这一点?我尝试编写下面的两个查询,但两次都得到了错误的结果。两个结果都只显示了 10003。

Select max(woWorker.pk) as  ToKeep, min(woWorker.Pk) as ToDelete
from woWorker 
group by woWorker.fkosCompanyWorker, woWorker.isActive
having (case when isActive = 'No' then 1 else 0 end) = 1


Select ToDelete = case when t.ToDelete is not null then t.ToDelete
                      else workers.worker end
from 
(Select Workers.worker as ToDelete, workerID
from Workers 
group by Workers.workerID, Workers.isActive, Workers.worker
having (case when isActive = 'No' then 1 else 0 end) = 1) t
join workers on t.workerID = workers.workerID
group by workers.workerID, t.ToDelete, workers.worker

标签: sqltsqlgroup-byduplicates

解决方案


您可以在这里使用旋转逻辑,例如

SELECT
    workerID,
    CASE WHEN MIN(isActive) <> MAX(isActive)
         THEN MAX(CASE WHEN isActive = 'Yes' THEN worker END)
         ELSE MIN(worker) END AS ToKeep,
    CASE WHEN MIN(isActive) <> MAX(isActive)
         THEN MAX(CASE WHEN isActive = 'No' THEN worker END)
         ELSE MAX(worker) END AS ToDelete
FROM Workers
GROUP BY
    workerID;

屏幕截图

演示

但是,如果您只想查看要保留的记录,那么ROW_NUMBER提供一种简单的方法来做到这一点:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY workerID ORDER BY isActive DESC, worker) rn
    FROM Workers
)

SELECT worker, workerID, isActive
FROM cte
WHERE rn = 1;

演示


推荐阅读