SQL(10)--统计当前title员工当前薪水平均工资(分组)、获取所有部门当前员工当前薪水最高(分组)

本文介绍如何使用SQL进行员工薪资的统计分析,包括按职位计算平均薪资及各部门当前最高薪资的员工信息。通过联接多个表格,筛选出特定条件下的数据,进行聚合运算。

考点:avg() group by

一.统计当前title员工当前薪水平均工资

题目描述

统计出当前(titles.to_date='9999-01-01')各个title类型对应的员工当前(salaries.to_date='9999-01-01')薪水对应的平均工资。结果给出title以及平均工资avg。
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));
CREATE TABLE IF NOT EXISTS "titles" (
`emp_no` int(11) NOT NULL,
`title` varchar(50) NOT NULL,
`from_date` date NOT NULL,

`to_date` date DEFAULT NULL);

输出描述

实现

select t.title,avg(s.salary) as avg
from titles as t,salaries as s 
on t.emp_no=s.emp_no
where t.to_date='9999-01-01'
and s.to_date='9999-01-01'
group by t.title

二.获取所有部门当前员工当前薪水最高

题目描述

获取所有部门中当前(dept_emp.to_date = '9999-01-01')员工当前(salaries.to_date='9999-01-01')薪水最高的相关信息,给出dept_no, emp_no以及其对应的salary
CREATE TABLE `dept_emp` (
`emp_no` int(11) NOT NULL,
`dept_no` char(4) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,

PRIMARY KEY (`emp_no`,`from_date`));

输出描述

select d.dept_no,d.emp_no,max(s.salary)
from dept_emp as d inner join salaries as s 
on d.emp_no=s.emp_no
and d.to_date = '9999-01-01'
and s.to_date = '9999-01-01'
group by dept_no

 

<think>好的,我现在需要帮助用户解决如何在SQL Server中连接titles和salaries统计各个title类型对应的员工当前薪水平均工资。首先,我得仔细理解用户的需,并参考之前的对话和提供的引用内容。 用户当前的问题是:如何通过连接这两个统计每个title的平均当前薪水。之前的对话中,用户询问了如何分组统计title的出现次数,现在的问题涉及到多连接和聚合函数的使用,同时需要处理“当前薪水的情况。 首先,我需要回顾引用内容。引用[1]、[2]、[3]、[4]、[5]都提到了类似的问题,即统计各个title平均工资。特别是引用[5]中的答案使用了LEFT JOIN,并且过滤了当前薪水(to_date='9999-01-01')。这说明在解决问题时,需要确保只考虑当前有效的记录。 接下来,我需要考虑SQL Server中的语法是否与其他数据库(如MySQL)有所不同。用户特别提到SQL Server,所以需要注意函数和语法是否适用。例如,使用GETDATE()获取当前日期可能更合适,但根据引用[5],他们使用了固定日期'9999-01-01'作为当前标志,这可能是数据设计中的惯例。 然后,分析结构。titles有emp_no, title, from_date, to_date;salaries有emp_no, salary, from_date, to_date。两个通过emp_no连接。为了获取当前记录,需要两个的to_date都为'9999-01-01',或者根据实际情况使用当前日期。 用户可能需要确保每个员工当前职称和当前薪水都被正确关联。因此,连接条件不仅要匹配emp_no,还要确保两个中的记录都是当前有效的。例如,t.to_date = '9999-01-01' AND s.to_date = '9999-01-01',或者在动态情况下使用WHERE t.to_date > GETDATE() AND s.to_date > GETDATE(),但根据引用中的例子,固定日期更可能。 接下来,考虑是否需要使用INNER JOIN还是LEFT JOIN。引用[5]使用了LEFT JOIN,但根据问题描述,可能需要INNER JOIN,因为只有同时存在当前职称和当前薪水员工才应被计入统计。如果使用LEFT JOIN,可能会导致职称存在但薪水不存在的情况,但用户可能需要排除这些情况。需要根据业务需决定,但通常INNER JOIN更合适。 然后,编写SQL语句的步骤应该是: 1. 连接titles和salaries,使用emp_no,并过滤当前有效的记录。 2. 按title分组。 3. 计算平均工资。 4. 按平均工资升序排序。 需要注意,在SQL Server中,别名在HAVING子句中不可用,所以排序时应使用别名或达式。引用[4]中的示例使用了ORDER BY avg ASC,其中avg是AVG(s.salary)的别名,这在SQL Server中是允许的。 可能的错误点包括未正确过滤当前记录,或者连接条件不准确。例如,如果忘记过滤to_date,可能会统计所有历史记录的平均值,而不是当前的情况。此外,确保分组正确,按title分组,而不是其他字段。 现在,验证引用中的示例是否正确。引用[5]的答案使用了LEFT JOIN,但可能应该用INNER JOIN,因为如果员工没有当前薪水,LEFT JOIN仍会保留title,但salary为NULL,导致avg计算时排除NULL值,但结果可能不正确。如果业务需是仅统计当前薪水title,则INNER JOIN更合适。 此外,是否需要考虑一个员工可能有多个title薪水记录?题目中的titles和salaries可能有多个历史记录,但通过过滤to_date='9999-01-01',每个员工应该只有一个当前职称和当前薪水,因此不需要去重。但如果有重复,可能需要使用DISTINCT,但根据问题描述,可能不需要,因为每个员工当前职称和薪水应该是唯一的。 最后,生成SQL语句时,应包含所有必要的部分:SELECT、FROM、JOIN、WHERE、GROUP BY、ORDER BY,并确保字段别名正确。例如: SELECT t.title, AVG(s.salary) AS avg_salary FROM titles t INNER JOIN salaries s ON t.emp_no = s.emp_no WHERE t.to_date = '9999-01-01' AND s.to_date = '9999-01-01' GROUP BY t.title ORDER BY avg_salary ASC; 或者使用GETDATE(): WHERE t.to_date > GETDATE() AND s.to_date > GETDATE() 但需要根据数据实际情况决定。根据引用中的例子,使用固定日期更可能正确。 总结步骤: 1. 连接两个,确保员工当前职称和当前薪水。 2. 按title分组。 3. 计算平均工资。 4. 排序。 需要提醒用户注意当前记录的过滤条件是否正确,以及连接方式的选择。</think>在SQL Server中连接`titles`和`salaries`统计title当前薪水平均工资的完整实现步骤如下: ### 一、完整SQL语句 ```sql SELECT t.title, AVG(s.salary) AS avg_salary FROM titles t INNER JOIN salaries s ON t.emp_no = s.emp_no AND t.to_date = '9999-01-01' -- 当前职称 AND s.to_date = '9999-01-01' -- 当前薪水 GROUP BY t.title ORDER BY avg_salary ASC; ``` ### 二、关键步骤解析 1. **连接条件** - 使用`INNER JOIN`确保只保留同时存在当前职称和当前薪水的记录[^5] - 通过`t.to_date = '9999-01-01'`限定当前有效职称(行业常用设计) - 通过`s.to_date = '9999-01-01'`限定当前有效薪水 2. **聚合计算** `AVG(s.salary)`自动忽略NULL值,因此无需额外处理空值[^4] 3. **排序控制** `ORDER BY avg_salary ASC`实现按平均工资升序排列(默认升序可省略ASC) ### 三、典型错误对比 错误写法(未过滤当前状态): ```sql SELECT title, AVG(salary) FROM titles JOIN salaries USING(emp_no) GROUP BY title ``` 此写法会统计所有历史记录的平均值,而非当前薪资 ### 四、扩展优化 若需动态判断当前日期: ```sql SELECT t.title, AVG(s.salary) AS avg_salary FROM titles t INNER JOIN salaries s ON t.emp_no = s.emp_no AND t.to_date > GETDATE() -- 动态判断当前职称 AND s.to_date > GETDATE() -- 动态判断当前薪水 GROUP BY t.title ORDER BY avg_salary; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值