跨表统计需先理清业务逻辑和关联路径,明确统计目标后反推所需表及连接方式,注意数据粒度、连接类型选择与分步验证。

跨表统计不是简单拼几个表,关键在理清业务逻辑和关联路径。先想清楚“我要算什么”“数据分散在哪几张表”“它们怎么连起来”,再动手写SQL。
明确统计目标,反推需要哪些表
比如要算“每个部门的在职员工平均薪资”,就得知道:部门信息在 departments 表,员工基本信息和部门ID在 employees 表,薪资记录可能在独立的 salaries 表(尤其有历史调薪时)。不能只连 employees 和 departments 就完事——如果薪资是最新一条,还得关联 salaries 并取 MAX(from_date) 或用窗口函数去重。
- 查平均薪资 → 必须包含 salaries 表
- 按部门分组 → departments 和 employees 都要有 dept_id 字段
- “在职”通常指 emp_status = 'Active' 或 contracts.end_date > TODAY → 要检查是否有合同/状态表
选对连接方式,避免漏数或翻倍
INNER JOIN 最安全,但会丢掉没薪资记录的员工;LEFT JOIN 更稳妥,但要注意:如果 salaries 表一对多(一个员工多条薪资记录),直接 LEFT JOIN 后 COUNT(*) 就会虚高。这时候得先聚合再连接。
- 错误写法:
FROM employees e LEFT JOIN salaries s ON e.emp_id = s.emp_id→ 员工A有3条薪资记录,GROUP BY 部门后,e.name 被重复计算3次 - 推荐写法:先用子查询或 CTE 算出每人最新薪资:
SELECT emp_id, MAX(from_date) AS max_date FROM salaries GROUP BY emp_id,再连回主表 - 部门可能有无人归属的情况?那就用 departments 左连 employees,确保部门不丢
分步写 + 临时验证,别硬套大SQL
复杂统计建议拆三步走:
- 第一步:单独查出带部门名称、员工ID、最新薪资的中间结果(加 LIMIT 10 看对不对)
- 第二步:在这个结果上 GROUP BY dept_name,试 SUM(salary) / COUNT(emp_id)
- 第三步:补 WHERE 过滤在职、时间范围等条件,最后加上 ROUND(AVG(salary),2) 美化输出
这样每步可验证,出错能快速定位是关联错了,还是聚合逻辑有问题。
标签: 聚合函数
还木有评论哦,快来抢沙发吧~