SQLite如何实现多列组合去重并提取关联数据

来源:站长平台作者:小鱼头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQLite如何实现多列组合去重并提取关联数据》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQLite如何实现多列组合去重并提取关联数据》有用,将其分享出去将是对创作者最好的鼓励。

在SQLite数据库的实际使用中,多列组合去重并提取关联数据是非常常见的需求,比如统计不同用户在不同分类下的唯一操作记录,或者获取每个商品不同批次的唯一库存信息等。这类需求不能仅依靠单列去重实现,需要结合多列判断和关联查询逻辑。

SQLite如何实现多列组合去重并提取关联数据

多列组合去重的基础方法

使用DISTINCT实现多列组合去重

DISTINCT关键字可以直接对多个列的组合进行去重,返回所有列组合唯一的记录。这种方式适合只需要获取去重后的多列值,不需要额外聚合计算的场景。

假设我们有如下用户操作记录表user_action:

iduser_idaction_typeaction_time
11001click2024-01-01 10:00:00
21001click2024-01-01 10:01:00
31001buy2024-01-01 10:02:00
41002click2024-01-01 10:03:00

如果需要获取所有唯一的user_id和action_type组合,可以使用以下查询:

-- 查询user_id和action_type的唯一组合
SELECT DISTINCT user_id, action_type
FROM user_action;

执行上述语句后,会返回user_id为1001、action_type为click,user_id为1001、action_type为buy,user_id为1002、action_type为click这三条唯一组合记录,重复的user_id 1001和action_type click的第二行记录会被过滤掉。

使用GROUP BY实现多列组合去重

GROUP BY同样可以实现多列组合去重,并且支持对去重后的分组进行聚合计算,适合需要同时获取去重组合和统计信息的场景。

还是以上面的user_action表为例,如果需要获取每个user_id和action_type组合的最早操作时间,可以使用GROUP BY:

-- 查询每个用户操作类型组合的最早操作时间
SELECT user_id, action_type, MIN(action_time) AS first_action_time
FROM user_action
GROUP BY user_id, action_type;

这里GROUP BY user_id, action_type会先对两列的组合进行分组去重,然后MIN(action_time)会计算每个分组中的最小操作时间,也就是最早的操作时间。

多列去重后提取关联数据

很多时候我们完成多列去重后,还需要提取去重记录对应的其他关联字段,比如上面例子中如果还需要获取每个唯一组合对应的最早操作记录的完整id,就不能直接用DISTINCT或者简单的GROUP BY,需要结合子查询或者关联查询实现。

使用子查询提取关联数据

可以先通过GROUP BY获取每个多列组合的唯一标识,再关联原表获取完整的关联数据。比如要获取每个user_id和action_type组合对应的最早操作记录的完整信息:

-- 先获取每个组合的最早操作时间,再关联原表获取完整记录
SELECT ua.*
FROM user_action ua
INNER JOIN (
    SELECT user_id, action_type, MIN(action_time) AS first_time
    FROM user_action
    GROUP BY user_id, action_type
) AS temp
ON ua.user_id = temp.user_id 
AND ua.action_type = temp.action_type 
AND ua.action_time = temp.first_time;

上述语句中,子查询先通过GROUP BY得到每个user_id和action_type组合的最早操作时间first_time,然后原表user_action和子查询结果通过user_id、action_type、action_time三个条件关联,就可以得到每个唯一组合对应的最早操作完整记录。

使用窗口函数提取关联数据

SQLite 3.25.0及以上版本支持窗口函数,使用ROW_NUMBER()可以更简洁地实现多列去重并提取关联数据的需求。还是上面的例子,获取每个user_id和action_type组合的最早操作完整记录:

-- 使用窗口函数给每个组合的记录排序,取排序第一的记录
SELECT id, user_id, action_type, action_time
FROM (
    SELECT *,
        ROW_NUMBER() OVER (
            PARTITION BY user_id, action_type 
            ORDER BY action_time ASC
        ) AS rn
    FROM user_action
)
WHERE rn = 1;

这里PARTITION BY user_id, action_type就是按照两列组合进行分区,也就是去重的维度,ORDER BY action_time ASC会让每个分区内的记录按操作时间升序排列,ROW_NUMBER()会给每个分区的记录从1开始编号,最后取rn=1的记录,就是每个组合的最早操作记录。

两种方案的选择建议

  • 如果只需要获取去重后的多列值,不需要其他关联字段,优先使用DISTINCT,语法更简洁。
  • 如果需要去重后做聚合计算,比如计数、求和等,优先使用GROUP BY。
  • 如果需要去重后提取完整的关联记录,且SQLite版本支持窗口函数,优先使用窗口函数方案,逻辑更清晰,扩展性更好。
  • 如果SQLite版本较低不支持窗口函数,再使用子查询关联的方案。

注意事项

在使用多列组合去重时,需要注意列值为NULL的情况,SQLite中NULL和NULL在DISTINCT和GROUP BY的判断中会被视为相等,也就是多个NULL值的组合也会被去重。如果业务上需要区分NULL值的不同情况,需要提前处理NULL值,比如用COALESCE函数将NULL转换为特定的占位值。

另外,如果去重的多列组合中存在大字段,比如很长的文本字段,DISTINCT和GROUP BY的比较效率会比较低,建议提前对数据进行预处理,或者给多列组合添加联合索引提升查询效率。

SQLite多列组合去重关联数据提取DISTINCTGROUP_BY修改时间:2026-07-19 20:36:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。