Window 从 SQL 服务器数据集中删除特定记录的函数

Window function to remove specific records from SQL Server dataset

我有一个 SQL 服务器查询 returns 一个数据集显示一个人的 ID、这个人工作的实体、属于该实体的位置、分配给案例的协调员和人的状态。

   ID    EntityName     LocationName      AssignedTo     StatusName
   17       F&S            St. Lucie         A Hardon       Active
   17       F&S            St. Lucie         A Hardon       Withdrawn
   18       F&S            NH                A Hardon       Withdrawn
   20       H&H            NCH               B Reedy        Active

我需要删除 EntityName、LocationName 和 AssignedTo 组合的唯一状态为 Withdrawn 的记录。所以在上面的数据集中,我想删除 ID = 18 和 LocationName = NH.

我试过使用 Window 函数,它可能在正确的路径上,但我不确定如何继续:

   Select id, entityname, locationname, assignedto, statusname
   Into #test
   From Table A

   Select *,
          row_number()over(partition by entityname, locationname, assignedto
                           order by case when statusname = 'Withdrawn' then 1
                                    else 2 end) as rn
  from #test

这给了我这样的结果:

    ID   EntityName   LocationName     AssignedTo     StatusName      RN
    17     F&S          St. Lucie        A Hardon       Withdrawn      1
    17     F&S          St. Lucie        A Hardon       Active         2
    18     F&S           NH              A Hardon       Withdrawn      1
    20     H&H           NCH             B Reedy        Active         1

但现在我不知道如何继续,或者我是否以错误的方式进行此操作。

换一种稍微不同的方式来思考这个问题。计算 撤回的人数。如果这是0,则全部撤回。

适当的 window 函数是条件聚合,而不是排名函数:

select t.*
from (Select t.*,
              sum(case when statusname <> 'Withdrawn' then 1 else 0 end) over
                  (partition by entityname, locationname, assignedto) as num_notwithdrawn
      from #test t
     ) t
where num_notwithdrawn = 0;
 Select id, entityname, locationname, assignedto, statusname,
    r   row_number()over(partition by entityname, locationname, assignedto
                   order by CASE statusname WHEN 'Withdrawn' THEN 1 ELSE 2 END) as rn Into #test From Table A
Select * from #test LEFT OUTER JOIN
  (
       SELECT MAX(rn) MRNO,ID FROM #test GROUP BY ID
  ) T ON T.ID = #TEST.ID WHERE rn = MRNO AND statusname ='Withdrawn'

这将针对实体名称、位置名称、分配给

的组合,单独删除状态为撤消的行

使用 INNER JOIN 删除

DELETE T
FROM Table T
INNER JOIN 
(
    SELECT EntityName,LocationName,AssignedTo
    FROM Table
    WHERE StatusName='Withdrawn'
    GROUP BY EntityName,LocationName,AssignedTo
    HAVING COUNT(*) = 1
)D ON D.EntityName=T.EntityName AND D.LocationName=T.LocationName AND D.AssignedTo=T.AssignedTo

试试下面的:

WITH CTE 
AS (
Select id, entityname, locationname, assignedto, statusname,
        row_number()over(partition by entityname, locationname, assignedto
                       order by statusname) as rn
  From Table A)
DELETE  from CTE where rn=1  and statusname = 'Withdrawn'

尝试使用 EXISTS

Select *
FROM    #test t1
WHERE   EXISTS (SELECT * 
                FROM #test t2 
                WHERE t1.EntityName = t2.EntityName 
                      and t1.LocationName = t2.LocationName 
                      and t1.AssignedTo = t2.AssignedTo 
                      and t2.StatusName <> 'Withdrawn')

为什么不使用内部联接识别潜在的删除,然后添加一个简单的 WHERE 子句来删除 'Withdrawn' 条目?

delete from #table a
inner join (
            select entityname, locationname, assignedto, count(*)
            from #table
            group by entityname, locationname, assignedto
            having count(*) = 1 ) b
            on b.entityname = a.entityname
            and b.locationname = a.locationname
            and b.assignedto = a.assignedto
where a.statusnname = 'Withdrawn'

内连接保持 'potential' 删除(e、l 和 a 的任意组合,只有一个记录),随后的 WHERE 子句删除适当的记录。