You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite删除STK_CODE重复行:保留min列最小值对应行的方案

作为SQLite新手遇到这种重复数据清理的问题很正常,我给你两种可行的方案,一种是纯SQL操作(适合快速验证效果),另一种是结合C++代码的实现(适合集成到你的项目里):

方案一:纯SQL语句解决

因为你的表没有主键,直接删除重复行需要先定位出要保留的记录,这里推荐用临时表的方法,逻辑清晰不容易出错:

  1. 创建临时表,存储每个STK_CODE对应min值最小的行
    把原表中需要保留的行筛选出来存入临时表:

    CREATE TEMP TABLE temp_table AS
    SELECT t1.*
    FROM your_table t1
    INNER JOIN (
        SELECT STK_CODE, MIN(min) AS min_val
        FROM your_table
        GROUP BY STK_CODE
    ) t2 ON t1.STK_CODE = t2.STK_CODE AND t1.min = t2.min_val;
    

    👉 注意把your_table替换成你实际的表名。

  2. 清空原表
    这一步会删除原表所有数据,所以操作前一定要备份数据库!

    DELETE FROM your_table;
    
  3. 将临时表的数据导回原表
    把筛选后的干净数据放回原表:

    INSERT INTO your_table SELECT * FROM temp_table;
    
  4. (可选)删除临时表
    SQLite的临时表会在会话结束后自动销毁,也可以手动删除:

    DROP TABLE temp_table;
    

如果你用的SQLite版本≥3.33.0(可以通过sqlite3 --version命令查看),也可以用更简洁的WITH子句直接删除重复行,不用临时表:

WITH to_keep AS (
    SELECT STK_CODE, MIN(min) AS min_val
    FROM your_table
    GROUP BY STK_CODE
)
DELETE FROM your_table
WHERE NOT EXISTS (
    SELECT 1 FROM to_keep
    WHERE your_table.STK_CODE = to_keep.STK_CODE AND your_table.min = to_keep.min_val
);

方案二:C++结合sqlite3库实现

如果你需要把这个逻辑集成到C++项目里,可以用sqlite3的C API来执行上述SQL语句,下面是完整的示例代码:

示例代码

#include <sqlite3.h>
#include <stdio.h>

// 清理重复行的函数
int removeDuplicateRows(sqlite3* db) {
    char* errMsg = nullptr;
    int rc;

    // 1. 创建临时表存储要保留的行
    const char* createTempSql = R"(
        CREATE TEMP TABLE temp_table AS
        SELECT t1.*
        FROM your_table t1
        INNER JOIN (
            SELECT STK_CODE, MIN(min) AS min_val
            FROM your_table
            GROUP BY STK_CODE
        ) t2 ON t1.STK_CODE = t2.STK_CODE AND t1.min = t2.min_val;
    )";
    rc = sqlite3_exec(db, createTempSql, nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "创建临时表失败: %s\n", errMsg);
        sqlite3_free(errMsg);
        return rc;
    }

    // 2. 清空原表
    const char* deleteSql = "DELETE FROM your_table;";
    rc = sqlite3_exec(db, deleteSql, nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "清空原表失败: %s\n", errMsg);
        sqlite3_free(errMsg);
        return rc;
    }

    // 3. 将临时表数据导回原表
    const char* insertSql = "INSERT INTO your_table SELECT * FROM temp_table;";
    rc = sqlite3_exec(db, insertSql, nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "导回数据失败: %s\n", errMsg);
        sqlite3_free(errMsg);
        return rc;
    }

    // 4. 可选:删除临时表
    const char* dropTempSql = "DROP TABLE temp_table;";
    rc = sqlite3_exec(db, dropTempSql, nullptr, nullptr, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "删除临时表失败: %s\n", errMsg);
        sqlite3_free(errMsg);
        return rc;
    }

    printf("重复行清理完成!\n");
    return SQLITE_OK;
}

int main() {
    sqlite3* db;
    // 打开数据库文件,替换成你的数据库路径
    int rc = sqlite3_open("your_database.db", &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return rc;
    }

    // 执行清理操作
    rc = removeDuplicateRows(db);

    // 关闭数据库连接
    sqlite3_close(db);
    return rc;
}

编译与运行

编译时需要链接sqlite3库,比如用g++的命令:

g++ your_code.cpp -o clean_duplicates -lsqlite3

运行编译后的程序即可完成重复行清理。


重要注意事项

  1. 备份数据库!:所有涉及删除数据的操作都有风险,一定要先备份你的数据库文件,避免数据丢失。
  2. 替换占位符:把代码和SQL中的your_table换成你实际的表名,your_database.db换成你的数据库文件路径。
  3. SQLite版本检查:如果想用WITH子句的方案,确保你的SQLite版本不低于3.33.0。

内容的提问来源于stack exchange,提问作者Hard work

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:28:30