繁体   English   中英

SQL 基于多个条件删除行

[英]SQL Delete Rows Based on Multiple Criteria

我正在尝试根据多个条件从数据集中删除行,但收到​​语法错误。 这是当前的代码:

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 如下所示:

在此处输入图片说明

我想删除所有 ID 和 Numb1 相同的记录。 所以我希望代码删除所有行,除了:

在此处输入图片说明

Vertica 中的 WITH 子句仅支持 SELECT 或 INSERT,不支持 DELETE/UPDATE。

Vertica 文档

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)

无法从 CTE 中删除。 只需手动使用删除语法但回滚事务,或者如果您有权限,您可以随时复制它并进行测试。

我对 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 这将删除至少存在另一个具有相同idnumb1记录的记录,这就是我了解您希望从您的示例数据和预期结果中获得的结果。

重要提示:确保在执行此操作之前备份整个表!

如果您将数据粘贴为文本而不是图片,您会为我节省大约 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; ,然后删除,然后重命名。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM