LEFT JOIN关联历史员工花名册出现重复数据问题求助
问题分析与解决方案
问题背景
现有两张业务表:
- 员工花名册表(
company.employee_roster):按周存储员工及主管信息,用于追踪主管变更,样本数据如下:
| week | employeeId | employeeName | supervisor |
|---|---|---|---|
| 2022-07-10 | 1 | David | Bob |
| 2022-07-10 | 2 | Joe | Bob |
| 2022-07-10 | 3 | Miriam | Martin |
| 2022-07-17 | 1 | David | Bob |
| 2022-07-17 | 2 | Joe | Bob |
| 2022-07-17 | 3 | Miriam | Martin |
- 销售数据表(
company.sales):记录员工每周销售业绩,样本数据如下:
| week | employeeId | sales |
|---|---|---|
| 2022-07-10 | 1 | $500 |
| 2022-07-10 | 2 | $400 |
| 2022-07-10 | 3 | $309 |
尝试用以下SQL关联两表以生成带主管信息的销售数据:
FROM company.sales AS t LEFT JOIN company.employee_roster AS roster ON roster.week = t.week AND roster.employeeId = t.employeeId
但关联后结果出现重复数据,移除JOIN语句则数据正常。
问题原因
你当前的关联逻辑本身是合理的,出现重复的核心原因有两种可能:
- 员工表存在重复记录:实际业务中可能存在同一
week + employeeId组合的多条重复录入,导致一条销售数据匹配到多条员工记录,最终生成重复行(样本数据中无此情况,但实际库可能存在)。 - SELECT字段不明确:若使用
SELECT *查询,两张表的同名字段(如week、employeeId)会重复显示,造成视觉上的“重复数据”误解。
优化方案
1. 先对员工表去重后关联
如果员工表确实存在重复的week + employeeId记录,先通过去重处理再关联:
FROM company.sales AS t LEFT JOIN ( SELECT DISTINCT week, employeeId, supervisor, employeeName FROM company.employee_roster ) AS roster ON roster.week = t.week AND roster.employeeId = t.employeeId
若需要保留最新的主管信息(比如存在时间戳字段),可使用窗口函数确保每个组合只取一条:
FROM company.sales AS t LEFT JOIN ( SELECT week, employeeId, supervisor, employeeName, ROW_NUMBER() OVER(PARTITION BY week, employeeId ORDER BY week DESC) AS rn FROM company.employee_roster ) AS roster ON roster.week = t.week AND roster.employeeId = t.employeeId AND roster.rn = 1
2. 明确指定查询字段
避免使用SELECT *,只选择业务需要的字段,消除字段重复的视觉混淆:
SELECT t.week, t.employeeId, roster.employeeName, roster.supervisor, t.sales FROM company.sales AS t LEFT JOIN company.employee_roster AS roster ON roster.week = t.week AND roster.employeeId = t.employeeId
3. 验证关联条件完整性
当前用week + employeeId作为关联键符合业务逻辑,若存在员工跨周调整主管的特殊场景,可补充其他维度(如员工状态字段),但现有条件已满足常规需求。
内容的提问来源于stack exchange,提问作者David Salomon
相关产品推荐
相关产品推荐

