CTE с DELETE - альтернатива хранилищу данных SQL - PullRequest
0 голосов
/ 11 февраля 2019

Я хотел бы удалить все строки в таблице, где batchId (порядковый номер) старше двух предыдущих.Я мог бы, вероятно, сделать это в базе данных SQL с помощью запроса:

WITH CTE AS(
    SELECT
        *,
        DENSE_RANK() OVER(ORDER BY BATCHID DESC) AS RN
    FROM MyTable
)
DELETE FROM CTE WHERE RN>2

Но то же самое недопустимо в хранилище данных SQL для этого .Ищите альтернативы здесь.

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019

Вы можете попробовать:

delete t from mytable t
    where batchId < (select max(batchid) from mytable);

О, если вы хотите оставить два, возможно, это будет работать:

delete t from mytable t
    where batchId < (select batchid
                     from mytable
                     group by batchid
                     limit 1 offset 1
                    );
0 голосов
/ 12 февраля 2019

Хранилище данных SQL Azure поддерживает только ограниченную площадь поверхности T-SQL и CTE для операций DELETE и DELETEs с предложениями FROM, что приведет к следующей ошибке:

Msg 100029, Уровень 16, Состояние 1, Строка 1
Предложение FROM в настоящее время не поддерживается в операторе DELETE.

Однако оно поддерживает подзапросы, поэтому один из способов написать ваше утверждение следующим образом:

DELETE dbo.MyTable
WHERE BATCHID Not In ( SELECT TOP 2 BATCHID FROM dbo.MyTable ORDER BY BATCHID DESC );

Этот синтаксис поддерживается в хранилище данных SQL Azure, и я его протестировал.Я не уверен, насколько эффективно это будет на миллиардах строк, хотя.Вы также можете подумать о переключении разделов.

Если вы удаляете большую часть своей таблицы, тогда может иметь смысл использовать CTAS для помещения данных, которые вы хотите сохранить, в новую таблицу, например что-то вроде этого:

-- Keep the most recent two BATCHIDS
CREATE TABLE dbo.MyTable2
WITH
(
    CLUSTERED COLUMNSTORE INDEX,
    DISTRIBUTION = HASH( BATCHID )
    -- Add partition scheme here if required
)
AS
SELECT  *
FROM dbo.MyTable
WHERE BATCHID In ( SELECT TOP 2 BATCHID FROM dbo.MyTable ORDER BY BATCHID DESC )
OPTION ( LABEL = 'CTAS : Keep top two BATCHIDs' );
GO

-- Rename or DROP old table
RENAME OBJECT dbo.MyTable TO MyTable_Old;
RENAME OBJECT dbo.MyTable2 TO MyTable;
GO

-- Optionally DROP MyTable_Old if everything has been successful
-- DROP TABLE MyTable_Old

Этот метод описан более подробно здесь .

0 голосов
/ 11 февраля 2019

Вы можете попробовать использовать JOIN

delete d from MyTable d
join 
(
 SELECT
        *,
        RN = ROW_NUMBER() OVER(PARTITION BY BATCH_ID ORDER BY BATCH_ID DESC)
    FROM MyTable
)A on d.batch_id=A.batch_id where RN >2
...