You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQLite全列重复行删除及CSV导入主键约束错误处理

1. 如何删除SQLite中所有列(含ID列)均重复的数据行?

在SQLite里处理全列重复的行,核心思路是先识别重复组,再保留每组中的一行、删除其余重复项。因为SQLite默认给每个表分配了ROWID(除非你创建了WITHOUT ROWID表),我们可以借助它来区分内容完全相同的行。

方法一:使用窗口函数(SQLite 3.25.0+支持)

窗口函数是最直观的实现方式,通过ROW_NUMBER()给每个重复组的行编号,然后删除编号大于1的重复行:

WITH duplicate_groups AS (
    SELECT *,
           -- 按所有列分组,给每组行按ROWID排序编号
           ROW_NUMBER() OVER (
               PARTITION BY C1, C2, ..., C15  -- 替换为你的所有列名
               ORDER BY ROWID
           ) AS row_num
    FROM Book1
)
DELETE FROM Book1
WHERE ROWID IN (SELECT ROWID FROM duplicate_groups WHERE row_num > 1);

PARTITION BY后必须列出表中所有列,确保只有当所有列内容都相同时才被归为一组。这里我们保留每组中ROWID最小的行,删除其他重复行。

方法二:自连接+分组(兼容旧版SQLite)

如果你的SQLite版本不支持窗口函数,可以用子查询分组取最小ROWID的方式实现:

DELETE FROM Book1
WHERE ROWID NOT IN (
    SELECT MIN(ROWID)
    FROM Book1
    GROUP BY C1, C2, ..., C15  -- 同样替换为所有列名
);

逻辑和方法一一致:按所有列分组,每组仅保留ROWID最小的那一行,其余重复行全部删除。

2. 解决临时表重复ID导致插入永久表主键约束错误的问题

根据你的描述,问题根源是临时表Book1中存在重复的C15值(对应永久表的RunId主键),导致插入时触发主键冲突。你可以选择先清理临时表的重复数据,或者直接在插入时处理重复,两种方案如下:

方案一:先清理临时表的重复ID,再插入

如果需要保留干净的临时表,先删除重复的ID行(这里假设只要C15重复就会引发冲突,无需考虑其他列):

-- 清理临时表:每个C15仅保留最早插入的一行
DELETE FROM Book1
WHERE ROWID NOT IN (
    SELECT MIN(ROWID)
    FROM Book1
    GROUP BY C15
);

-- 插入到永久表
INSERT INTO permanent_table (RunId, col1, col2, ...)  -- 替换为永久表的列名
SELECT C15, col1, col2, ... FROM Book1;  -- 对应临时表的列

如果需要确保所有列都重复才删除(而非仅ID重复),可以复用第一个问题中的全列分组方法。

方案二:插入时直接去重,无需修改临时表

如果你不需要保留去重后的临时表,可以直接在插入语句中处理重复,省去删除步骤:

  • DISTINCT过滤全列重复的行:
INSERT INTO permanent_table (RunId, col1, col2, ...)
SELECT DISTINCT C15, col1, col2, ... FROM Book1;
  • 或者按C15分组,选择每组中某一行的数据(比如用MAX/MIN提取其他列的值):
INSERT INTO permanent_table (RunId, col1, col2, ...)
SELECT C15, MAX(col1), MAX(col2), ...  -- 根据需求选择MAX/MIN
FROM Book1
GROUP BY C15;

这种方式适合你只关心RunId唯一,其他列可保留任意一行的场景。


内容的提问来源于stack exchange,提问作者Behrooz Karjoo

火山引擎 最新活动