SQL Удалить строки на основе нескольких критериев - PullRequest
1 голос
/ 30 января 2020

Я пытаюсь удалить строки из набора данных на основе нескольких критериев, но получаю синтаксическую ошибку. Вот текущий код:

With cte As (
        Select *, 
                Row_Number() Over(Partition By ID, Numb1 Order by ID) as RowNumb
        from DataSet
)
Delete from cte Where RowNumb > 1;

Где DataSet выглядит следующим образом:

enter image description here

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

enter image description here

Ответы [ 5 ]

0 голосов
/ 30 января 2020

Вы бы спасли меня ~ 5 минут, если бы вы вставили данные в виде текста, а не в виде рисунка - поскольку я не мог скопировать-вставить и пришлось бы перепечатывать ...

Сказав это:

Перестройте таблицу здесь:

DROP TABLE IF EXISTS input;
CREATE TABLE input(id,numb1,state_coding) AS (
          SELECT 202003,4718868,'D'
UNION ALL SELECT 202003,  35756,'AA'
UNION ALL SELECT 204281, 146199,'D'
UNION ALL SELECT 204281, 146199,'D'
UNION ALL SELECT 204346, 108094,'D'
UNION ALL SELECT 204346, 108094,'D'
UNION ALL SELECT 204389,  14642,'DD'
UNION ALL SELECT 204389,  96504,'F'
UNION ALL SELECT 204392,  22010,'D'
UNION ALL SELECT 204392,   8051,'G'
UNION ALL SELECT 204400,  74118,'D'
UNION ALL SELECT 204400, 103900,'D'
UNION ALL SELECT 204406,1387304,'D'
UNION ALL SELECT 204406,      0,'HJ'
UNION ALL SELECT 204516,    894,'D'
UNION ALL SELECT 204516,   3927,'D'
UNION ALL SELECT 204586, 234235,'D'
UNION ALL SELECT 204586, 234235,'D'
)
;

И затем: на основе того, что было сказано в других ответах, и с учетом того, что массовое удаление важной части таблицы не только в Vertica , лучше всего реализовать как INSERT ... SELECT с инвертированным условием WHERE - здесь идет:

CREATE TABLE input_help AS
SELECT * FROM input
GROUP BY id,numb1,state_coding
HAVING COUNT(*) = 1;

DROP TABLE input;
ALTER TABLE input_help RENAME TO input;

По крайней мере, это работает с такой простотой, если вся строка одинакова - я заметил, что вы этого не делаете Поместите state_coding в условие самостоятельно. В противном случае все становится немного сложнее.

Или вы хотите заново вставлять по одной строке дубликатов каждый потом?

Затем просто создайте input_help как SELECT DISTINCT * FROM input;, затем бросьте , затем переименуйте.

0 голосов
/ 30 января 2020

Я не очень разбираюсь в Vertica, но кажется, что он не очень гибок в отношении delete операторов.

Один из способов сделать это - использовать временную таблицу для хранения нужных вам строк. сохранить, затем обрезать исходную таблицу и вставить обратно в нее из временной таблицы:

create temporary table MyTempTable as
select id, numb1, state_coding
from (select t.*, count(*) over(partition by id, numb1) cnt from DataSet) as t
where cnt = 1;

truncate table DataSet;

insert into DataSet
select id, numb1, state_coding from MyTempTable;

Обратите внимание, что вместо row_number я использовал счетчик окон. Это приведет к удалению записей, для которых существует по крайней мере другая запись с теми же id и numb1, что, как я понимаю, требуется от ваших образцов данных и ожидаемых результатов.

Внимание: обязательно сделайте резервную копию вся ваша таблица, прежде чем вы это сделаете!

0 голосов
/ 30 января 2020

Cte является временной таблицей. Вы не можете удалить из него. Это эффективно только для чтения.

Если вы пытаетесь удалить дубликаты из исходной таблицы DataSet, вы должны удалить из DataSet, а не из таблицы cte.

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

with cte as
(
	select
		ID,
		Row_Number() Over(Partition By ID, Numb1 Order by ID) as RowNumb
    from
		DataSet
)
delete from DataSet where ID in (select ID from cte where RowNumb > 1)
0 голосов
/ 30 января 2020

Невозможно удалить из CTE. Просто вручную используйте синтаксис удаления, но откат транзакций или, если у вас есть разрешения, вы всегда можете скопировать его и протестировать.

0 голосов
/ 30 января 2020

С предложениями в Vertica поддерживают только SELECT или INSERT, но не DELETE / UPDATE.

Документация Vertica

...