簡體   English   中英

如何按組刪除 SQL 服務器中除第一行和最后一行之外的所有行?

[英]How to delete all rows by group except the first and the last one in SQL Server?

我有這樣的數據

Id Name AuthorId 
----------------
1  AAA  2
2  BBB  2
3  CCC  2
4  DDD  3
5  EEE  3

我需要一個查詢,如果有超過 2 行,將按組 AuthorId 刪除所有行,但第一個和最后一個除外。

比如上面的數據,應該刪除第二行,因為對於AuthorId = 2 ,我有 3 行,但是對於AuthorId = 3 ,什么都不會被刪除

Row_number()兩次並刪除非終端

delete t
from (
   select *,
      row_number() over(partition by [AuthorId]  order by [Id]) n1,
      row_number() over(partition by [AuthorId]  order by [Id] desc) n2
   from tablename
) t
where n1 > 1 and n2 > 1

您可以嘗試對 min 和 max id 使用聯合,而不是在此子查詢的結果中

delete from my_table 
where id  NOT  IN  (


    select  min(id) 
    from my_table 
    group by AuthorId 
    union 
    select max(id)
    from my_table 
    group by AuthorId 

)

你可以試試這個:

Declare @t table (id int,name varchar(50),Authorid int)

insert into @t values (1,'AAA',2)
insert into @t values (2,'BBB',2)
insert into @t values (3,'CCC',2)
insert into @t values (4,'FFF',2)
insert into @t values (5,'DDD',3)
insert into @t values (6,'EEE',3)
;with cte as
(
select * from (
select *,count(*) over (partition by authorid) cnt from @t
) t
where cnt > 2
)

delete a from cte b join @t a on a.id=b.id where b.id not in (select min(id) from cte group by Authorid) and b.id not in (select max(id) from cte group by Authorid)

select * from @t

嘗試這個,

Declare @Temp_Data table (id int,name varchar(50),Authorid int)

insert into @Temp_Data values (1,'AAA',2)
insert into @Temp_Data values (2,'BBB',2)
insert into @Temp_Data values (3,'CCC',2)
insert into @Temp_Data values (4,'DDD',3)
insert into @Temp_Data values (5,'EEE',3)

Delete a
from @Temp_Data as a
inner join @Temp_Data as b on a.authorid=b.authorid and b.id > a.id
inner join @Temp_Data as c on a.authorid=c.authorid and c.id < a.id

select * from @Temp_Data

隨着EXISTS

delete t
from tablename t
where 
  exists (
    select 1 from tablename
    where authorid = t.authorid and id > t.id
  )
  and
  exists (
    select 1 from tablename
    where authorid = t.authorid and id < t.id
  )

請參閱演示
結果:

Id  Name    AuthorId
1   AAA     2
3   CCC     2
4   DDD     3
5   EEE     3

我會使用可更新的公用表表達式:

with cte as (
    select
        rank() over(partition by AuthorId order by id) rn_asc,
        rank() over(partition by AuthorId order by id desc) rn_desc
    from mytable
)
delete from cte when rn_asc = 1 or rn_desc = 1

在 cte 中,我們通過升序和降序計算AuthorID組中記錄等級的總和id 然后外部查詢刪除除頂部和底部記錄之外的所有內容。 如果存在最高或最低平局,它們將被保留(您可能希望為排名指定額外的排序標准以打破平局)。

注意cte中的其他表列不需要select; 只需 select 行列就足夠了,這是確定哪些記錄應刪除所需的唯一信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM