题解 | 统计员工薪资扣除比例
统计员工薪资扣除比例
https://www.nowcoder.com/practice/08db6f0135664ca598b579f8d53dc486
select sta.staff_id,sta.staff_name,concat(round((sal.dock_salary/sal.normal_salary)*100,1),'%') as dock_ratio from staff_tb sta join salary_tb sal on sta.staff_id = sal.staff_id where sta.department = 'dep1' order by dock_ratio desc
首先是学习了一个新的函数,concat(),查了一下用法之前自己做个笔记,用于字符串的拼接
这里也可以看到有意思的一点,我以为转百分比有特定的函数,没想到也可以通过拼接的方式去实现,类似此类关于表现形式的,其实只需要追求能实现最终的效果就行
说一下concat()函数吧,concat(column1,'+',column,'+','%')
英文逗号隔开,字符串用引号
第二点就是group by 的使用逻辑
本体因为staff_id唯一,不用分组计算,我误认为即使group一下,也能正常运行
但SQL 的分组查询(GROUP BY)遵循 **「SELECT 子句中的列,必须是 GROUP BY 的分组列,或被聚合函数(如 SUM/COUNT/MAX)包裹」**
也就是staff_name和dock_ratio并没有被分组选中,也没有执行聚合函数,违反了语法规则
理解偏差在于:误以为GROUP BY sta.staff_id是对「员工 ID 唯一的行」去重 / 分组,但实际上你的原查询中sta.staff_id和sal.staff_id关联后,本身已经是「一行员工对应一行薪资」的结果(即每个员工 ID 只有一条记录),此时添加GROUP BY是「无意义的分组」,且触发了 SQL 的语法规则限制。
若薪资表(salary_tb)存在「一个员工多条薪资记录」(需真正分组)
如果salary_tb中一个员工 ID 对应多条薪资记录(如月度薪资),此时需要分组聚合后计算扣薪比例,需对薪资列使用聚合函数(如 SUM/AVG),并将staff_name加入 GROUP BY(或用聚合函数包裹)
