Как удалить все строки между двумя числовыми значениями в столбце - PullRequest
0 голосов
/ 31 мая 2018

У меня есть таблица с двумя столбцами, 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

Ответы [ 4 ]

0 голосов
/ 31 мая 2018

Сначала вы должны определить границы того, что вы хотите удалить:

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 (выражение общей таблицы)) сделать фактическое удаление:

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
0 голосов
/ 31 мая 2018

Попробуйте это

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
0 голосов
/ 31 мая 2018

Это классический вопрос о типах пробелов и островков.Я рекомендую вам прочитать эту превосходную статью о пробелах и островках.

Вы можете использовать запрос, подобный приведенному ниже См. Работудемо

;
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
0 голосов
/ 31 мая 2018

этот запрос должен работать

delete from @tb1 where id < 13 and id > 9

удалить там, где тип находится между 10 и 12 [границы включены]

...