如何按组删除 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
,什么都不会被删除
您可以尝试对最小和最大 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
)
与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
)
参见demo。
结果:
Id Name AuthorId
1 AAA 2
3 CCC 2
4 DDD 3
5 EEE 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
你可以试试这个:
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
我有这样的数据
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
,什么都不会被删除
您可以尝试对最小和最大 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
)
与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
)
参见demo。
结果:
Id Name AuthorId
1 AAA 2
3 CCC 2
4 DDD 3
5 EEE 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
你可以试试这个:
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