如何删除列中两个数值之间的所有行
How to delete all rows between two number values in a column
我有一个包含两列的 table,id
和 typ
:
DECLARE @tb1 AS TABLE (id INT, typ INT)
INSERT INTO @tb1
(
id,
typ
)
VALUES
(1,1),(2,3),(3,2),(4,3),(5,1),(6,2),(7,3),(8,3),(9,1)
,(10,3),(11,3),(12,3),(13,2),(14,3),(15,1)
查看按 id
排序的行时,我想删除 typ = 1
行和下 typ = 2
行之间的所有行。
我想要这个结果:
id typ
----------- -----------
1 1
3 2
4 3
5 1
6 2
7 3
8 3
9 1
13 2
14 3
15 1
这个查询应该有效
delete from @tb1 where id < 13 and id > 9
删除典型值介于 10 和 12 之间的 [包括边框]
试试这个
DECLARE @idtype1 int, @idtype2 int
DECLARE type_cursor CURSOR FOR
SELECT a.ID as ID_TYPE_1, b.ID as ID_TYPE_2
FROM (SELECT ID, ROW_NUMBER() OVER(ORDER BY_ID) AS RN
FROM TABLE WHERE TYPE = 1) a
INNER JOIN (SELECT ID, ROW_NUMBER() OVER(ORDER BY_ID) AS RN
FROM TABLE WHERE TYPE = 2) b
ON a.RN = b.RN
OPEN type_cursor
FETCH NEXT FROM type_cursor
INTO @idtype1, @idtype2
WHILE @@FETCH_STATUS = 0
BEGIN
DELETE FROM TABLE WHERE ID BETWEEN @idtype1 AND @idtype2
END
这是一道经典的空白和孤岛问题类型的问题。
我建议你通读这篇优秀的 article on gaps and islands。
您可以使用如下查询
See working demo
;
with BoundarySuspects as
(
select
a.*,
seqNumber=row_number() over( order by id asc)
from @tb1 a
where a.typ=1 or a.typ=2
),
GapMap as
(
select
GapFrom= a.id,
GapTill= b.id
from BoundarySuspects a
join
BoundarySuspects b
on a.typ=1 and b.typ=2 and b.seqNumber=a.seqNumber+1
)
select
t.*
from @tb1 t
left join
GapMap g
on t.id >GapFrom and t.id <GapTill
where GapFrom is NULL
首先,您必须确定要删除的内容的边界:
SELECT
T1.id as StartId,
(SELECT MIN(T2.id) from @tb1 T2 WHERE T1.id < T2.id and T2.typ = 2) as EndId
from @tb1 T1
WHERE T1.typ = 1
结果:
StartId EndId
1 3
5 6
9 13
15 NULL
然后您可以在 CTE(通用 Table 表达式)中使用此查询来执行实际删除操作:
DECLARE @tb1 AS TABLE (id INT, typ int)
INSERT INTO @tb1 (id, typ)
VALUES (1,1),(2,3),(3,2),(4,3),(5,1),(6,2),(7,3),(8,3),(9,1),(10,3),(11,3),(12,3),(13,2),(14,3),(15,1)
;WITH ranges AS (
SELECT
T1.id as StartId,
(SELECT MIN(T2.id) from @tb1 T2 WHERE T1.id < T2.id and T2.typ = 2) as EndId
FROM @tb1 T1
WHERE T1.typ = 1
)
DELETE T3
FROM @tb1 T3
INNER JOIN ranges ON T3.id > ranges.StartId and T3.id < ranges.EndId
SELECT * FROM @tb1
我有一个包含两列的 table,id
和 typ
:
DECLARE @tb1 AS TABLE (id INT, typ INT)
INSERT INTO @tb1
(
id,
typ
)
VALUES
(1,1),(2,3),(3,2),(4,3),(5,1),(6,2),(7,3),(8,3),(9,1)
,(10,3),(11,3),(12,3),(13,2),(14,3),(15,1)
查看按 id
排序的行时,我想删除 typ = 1
行和下 typ = 2
行之间的所有行。
我想要这个结果:
id typ
----------- -----------
1 1
3 2
4 3
5 1
6 2
7 3
8 3
9 1
13 2
14 3
15 1
这个查询应该有效
delete from @tb1 where id < 13 and id > 9
删除典型值介于 10 和 12 之间的 [包括边框]
试试这个
DECLARE @idtype1 int, @idtype2 int
DECLARE type_cursor CURSOR FOR
SELECT a.ID as ID_TYPE_1, b.ID as ID_TYPE_2
FROM (SELECT ID, ROW_NUMBER() OVER(ORDER BY_ID) AS RN
FROM TABLE WHERE TYPE = 1) a
INNER JOIN (SELECT ID, ROW_NUMBER() OVER(ORDER BY_ID) AS RN
FROM TABLE WHERE TYPE = 2) b
ON a.RN = b.RN
OPEN type_cursor
FETCH NEXT FROM type_cursor
INTO @idtype1, @idtype2
WHILE @@FETCH_STATUS = 0
BEGIN
DELETE FROM TABLE WHERE ID BETWEEN @idtype1 AND @idtype2
END
这是一道经典的空白和孤岛问题类型的问题。 我建议你通读这篇优秀的 article on gaps and islands。
您可以使用如下查询 See working demo
;
with BoundarySuspects as
(
select
a.*,
seqNumber=row_number() over( order by id asc)
from @tb1 a
where a.typ=1 or a.typ=2
),
GapMap as
(
select
GapFrom= a.id,
GapTill= b.id
from BoundarySuspects a
join
BoundarySuspects b
on a.typ=1 and b.typ=2 and b.seqNumber=a.seqNumber+1
)
select
t.*
from @tb1 t
left join
GapMap g
on t.id >GapFrom and t.id <GapTill
where GapFrom is NULL
首先,您必须确定要删除的内容的边界:
SELECT
T1.id as StartId,
(SELECT MIN(T2.id) from @tb1 T2 WHERE T1.id < T2.id and T2.typ = 2) as EndId
from @tb1 T1
WHERE T1.typ = 1
结果:
StartId EndId
1 3
5 6
9 13
15 NULL
然后您可以在 CTE(通用 Table 表达式)中使用此查询来执行实际删除操作:
DECLARE @tb1 AS TABLE (id INT, typ int)
INSERT INTO @tb1 (id, typ)
VALUES (1,1),(2,3),(3,2),(4,3),(5,1),(6,2),(7,3),(8,3),(9,1),(10,3),(11,3),(12,3),(13,2),(14,3),(15,1)
;WITH ranges AS (
SELECT
T1.id as StartId,
(SELECT MIN(T2.id) from @tb1 T2 WHERE T1.id < T2.id and T2.typ = 2) as EndId
FROM @tb1 T1
WHERE T1.typ = 1
)
DELETE T3
FROM @tb1 T3
INNER JOIN ranges ON T3.id > ranges.StartId and T3.id < ranges.EndId
SELECT * FROM @tb1