Удаление записей от таблицы SQL Server без курсора

Никакое преступление, но это неумно для изменения класса на лету, поскольку это вынуждает интерпретатор CSS повторно вычислить визуальное представление всей веб-страницы.

причина состоит в том, что для интерпретатора CSS почти невозможно знать, могли ли какое-либо наследование или расположение каскадом быть изменены, таким образом, короткий ответ:

Никогда имя класса изменения на лету!-)

, Но обычно необходимо будет только изменить свойство или два, и это легко реализовано:

function highlight(elm){
    elm.style.backgroundColor ="#345";
    elm.style.color = "#fff";
}
6
задан Sam 10 August 2014 в 16:03
поделиться

5 ответов

Существует оператор WHILE , который является альтернативой курсору. Это в сочетании с табличными переменными может позволить вам делать то же самое в пределах производительности, с которой вы согласны.

0
ответ дан 17 December 2019 в 04:50
поделиться

Я не думаю, что то, о чем вы просите, возможно, но вы можете приблизиться. Похоже, вы можете почти сделать это, найдя записи с самосоединением вроде этого:

SELECT t1.id
FROM
  table t1 JOIN table t2 ON (
    t1.unitid = t2.unitid AND
    t1.day = t2.day AND
    t1.interval = t2.interval - 1
  )

, но проблема в том, что это тоже найдет id = 6. Однако, если вы создаете временную таблицу из этих данных, она может быть намного меньше, чем ваши исходные данные, и, таким образом, сканирование с помощью курсора будет намного быстрее (чтобы исправить проблему с id = 6). Затем вы можете выполнить DELETE FROM table WHERE id IN (SELECT id FROM tmp_table) , чтобы уничтожить строки.

Может быть способ исправить проблему с ID = 6 без курсора, но если так что я этого не вижу.

1
ответ дан 17 December 2019 в 04:50
поделиться

См. Эти статьи в моем блоге для получения подробной информации о производительности:


Основная идея приведенного ниже запроса заключается в том, что мы должны удалить все четные строки из непрерывных диапазонов интервалов.

То есть, если для заданного (unitId, Day) у нас есть следующие интервалы :

1
2
3
4
6
7
8
9

, у нас есть два непрерывных диапазона:

1
2
3
4

и

6
7
8
9

, и мы должны удалить каждую четную строку:

1
2 -- delete
3
4 -- delete

и

6
7 -- delete
8
9 -- delete

, чтобы мы получили:

1
3
6
8

Обратите внимание, что «четные строки "означает" даже для диапазона ROW_NUMBER () s "здесь, а не" четные значения interval ] ".

Вот запрос:

DECLARE @Table TABLE (ID INT, UnitID INT, [Day] INT, Interval INT, Amount FLOAT)

INSERT INTO @Table VALUES (1, 100, 10, 21, 9.345)
INSERT INTO @Table VALUES (2, 100, 10, 22, 9.345)
INSERT INTO @Table VALUES (3, 200, 11, 21, 9.345)
INSERT INTO @Table VALUES (4, 300, 11, 21, 9.345)
INSERT INTO @Table VALUES (5, 300, 11, 22, 9.345)
INSERT INTO @Table VALUES (6, 300, 11, 23, 9.345)
INSERT INTO @Table VALUES (7, 400, 13, 21, 9.345)
INSERT INTO @Table VALUES (8, 400, 13, 22, 9.345)
INSERT INTO @Table VALUES (9, 400, 13, 23, 9.345)
INSERT INTO @Table VALUES (10, 400, 13, 24, 9.345)
INSERT INTO @Table VALUES (11, 400, 13, 26, 9.345)
INSERT INTO @Table VALUES (12, 400, 13, 27, 9.345)
INSERT INTO @Table VALUES (13, 400, 13, 28, 9.345)
INSERT INTO @Table VALUES (14, 400, 13, 29, 9.345)

;WITH   rows AS
        (
        SELECT  *,
                ROW_NUMBER() OVER
                (
                PARTITION BY
                        (
                        SELECT  TOP 1 qi.id AS mint
                        FROM    @Table qi
                        WHERE   qi.unitid = qo.unitid
                                AND qi.[day] = qo.[day]
                                AND qi.interval <= qo.interval
                                AND NOT EXISTS
                                (
                                SELECT  NULL
                                FROM    @Table t
                                WHERE   t.unitid = qi.unitid
                                        AND t.[day] = qi.day
                                        AND t.interval = qi.interval - 1
                                )
                        ORDER BY
                                qi.interval DESC
                        )
                ORDER BY interval
                ) AS rnm
        FROM    @Table qo
        )
DELETE
FROM    rows
WHERE   rnm % 2 = 0

SELECT  *
FROM    @table

Обновление:

Вот более эффективный запрос:

DECLARE @Table TABLE (ID INT, UnitID INT, [Day] INT, Interval INT, Amount FLOAT)

INSERT INTO @Table VALUES (1, 100, 10, 21, 9.345)
INSERT INTO @Table VALUES (2, 100, 10, 22, 9.345)
INSERT INTO @Table VALUES (3, 200, 11, 21, 9.345)
INSERT INTO @Table VALUES (4, 300, 11, 21, 9.345)
INSERT INTO @Table VALUES (5, 300, 11, 22, 9.345)
INSERT INTO @Table VALUES (6, 300, 11, 23, 9.345)
INSERT INTO @Table VALUES (7, 400, 13, 21, 9.345)
INSERT INTO @Table VALUES (8, 400, 13, 22, 9.345)
INSERT INTO @Table VALUES (9, 400, 13, 23, 9.345)
INSERT INTO @Table VALUES (10, 400, 13, 24, 9.345)
INSERT INTO @Table VALUES (11, 400, 13, 26, 9.345)
INSERT INTO @Table VALUES (12, 400, 13, 27, 9.345)
INSERT INTO @Table VALUES (13, 400, 13, 28, 9.345)
INSERT INTO @Table VALUES (14, 400, 13, 29, 9.345)

;WITH    source AS
        (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY unitid, day ORDER BY interval) rn
        FROM    @Table
        ),
        rows AS
        (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY unitid, day, interval - rn ORDER BY interval) AS rnm
        FROM    source
        )
DELETE
FROM    rows
WHERE   rnm % 2 = 0

SELECT  *
FROM    @table
4
ответ дан 17 December 2019 в 04:50
поделиться
DECLARE @Table TABLE (ID INT, UnitID INT, [Day] INT, Interval INT, Amount FLOAT)

INSERT INTO @Table VALUES (1, 100, 10, 21, 9.345)
INSERT INTO @Table VALUES (2, 100, 10, 22, 9.367)
INSERT INTO @Table VALUES (3, 200, 11, 21, 4.150)
INSERT INTO @Table VALUES (4, 300, 11, 21, 4.350)
INSERT INTO @Table VALUES (5, 300, 11, 22, 4.734)
INSERT INTO @Table VALUES (6, 300, 11, 23, 5.106)
INSERT INTO @Table VALUES (7, 400, 13, 21, 10.257)
INSERT INTO @Table VALUES (8, 400, 13, 22, 10.428)

DELETE FROM @Table
WHERE ID IN (
  SELECT t1.ID
  FROM @Table t1
       INNER JOIN @Table t2 
            ON  t2.UnitID = t1.UnitID 
                AND t2.Day = t1.Day 
                AND t2.Interval = t1.Interval - 1
       LEFT OUTER JOIN @Table t3 
            ON  t3.UnitID = t2.UnitID 
                AND t3.Day = t2.Day 
                AND t3.Interval = t2.Interval - 1
  WHERE t3.ID IS NULL)

SELECT * FROM @Table
0
ответ дан 17 December 2019 в 04:50
поделиться

Ливен так близок - он работал для тестового набора,но если я добавлю еще несколько записей, некоторые начнут пропускаться.

Мы не можем использовать какие-либо критерии четности / нечетности - мы понятия не имеем, как падают данные.

Добавьте эти данные и повторите попытку:

INSERT @Table VALUES (9,    100,     10,   23,        9.345)

INSERT @Table VALUES (10,   100,     10,   24,        9.367)

INSERT @Table VALUES (11,   100,     10,   25,        4.150)

INSERT @Table VALUES (12,   100,     10,   26,        4.350)

INSERT @Table VALUES (13,   300,     11,   25,        4.734)

INSERT @Table VALUES (14,   300,     11,   26,        5.106)

INSERT @Table VALUES (15,   300,     11,   27,       10.257)

INSERT @Table VALUES (16,   300,     11,   29,       10.428)
0
ответ дан 17 December 2019 в 04:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: