多主键表合并后出现重复customer_id,求生成目标表want的解决方案
SQL查询去重生成目标表方案
问题背景
- 需从
customer_tb与study_history两张表生成名为want的新表 - 两张表的主键已用黄色标注(表结构参考:表结构示意图)
- 当前查询出现
customer_id重复问题,需去除重复值并匹配want表格式
核心原因
重复的本质是study_history表中单个customer_id对应多条记录,与customer_tb关联时产生笛卡尔积,导致用户信息被重复输出。
针对性解决方案
根据want表的具体需求,提供三种常用处理方式:
1. 保留用户最新/指定学习记录
如果需要为每个用户保留一条学习记录(比如最新的),用窗口函数实现精准筛选:
WITH ranked_study AS ( SELECT customer_id, -- 按需选择study_history表的字段 study_date, study_content, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY study_date DESC) AS rn FROM study_history ) SELECT c.*, s.study_date, s.study_content INTO want FROM customer_tb c LEFT JOIN ranked_study s ON c.customer_id = s.customer_id WHERE s.rn = 1 OR s.rn IS NULL; -- 包含无学习记录的用户
2. 聚合用户学习记录
如果需要合并同一用户的多条学习信息(比如统计次数、合并内容),使用聚合函数分组:
SELECT c.customer_id, c.customer_name, -- 其他customer_tb的字段 COUNT(s.study_id) AS total_studies, STRING_AGG(s.study_content, ', ') AS combined_studies -- PostgreSQL语法;MySQL用GROUP_CONCAT,SQL Server用STRING_AGG INTO want FROM customer_tb c LEFT JOIN study_history s ON c.customer_id = s.customer_id GROUP BY c.customer_id, c.customer_name; -- 按customer_tb的主键字段分组
3. 仅保留用户基础信息
如果want表只需要用户基础数据,无需学习记录,直接去重或查询原表:
-- 方式1:关联后去重 SELECT DISTINCT c.* INTO want FROM customer_tb c LEFT JOIN study_history s ON c.customer_id = s.customer_id; -- 方式2:直接取用户表数据(更高效) SELECT * INTO want FROM customer_tb;
关键注意事项
- 分组或窗口函数的
PARTITION BY必须基于customer_tb的主键(黄色标注字段),确保分组逻辑正确 - 根据使用的数据库类型调整聚合函数语法,避免语法错误
内容的提问来源于stack exchange,提问作者SANGBEUM DO
相关产品推荐
相关产品推荐

