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 子句删除适当的记录。
我有一个 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 子句删除适当的记录。