如何合并两个独立查询结果?员工表两类平均薪资差值计算问询
嘿,我来帮你解决这两个SQL问题哈!
问题1:如何合并两个独立查询的结果?
合并两个独立查询的结果,主要靠UNION和UNION ALL这两个关键字,我给你捋清楚它们的区别和用法:
UNION ALL:这是最直接的拼接方式,会把两个查询的结果原封不动地连在一起,哪怕有重复行也会保留,执行速度更快,适合不需要去重的场景。就像你代码里用到的那样,语法示例是这样的:
要注意哦,两个查询返回的列数必须一致,列的数据类型也要匹配,最终结果的列名会沿用第一个查询的列名。SELECT column1, column2 FROM table1 UNION ALL SELECT column1, column2 FROM table2;UNION:如果需要合并后自动去重并排序,就用这个。它会先把两个结果集的重复行去掉,再返回唯一的记录,不过因为多了去重和排序的步骤,效率会比UNION ALL低一些。语法很简单,去掉ALL就行:SELECT column1, column2 FROM table1 UNION SELECT column1, column2 FROM table2;
问题2:计算两种场景下的平均薪资差值
看你现在的写法,是用UNION ALL把两个平均值分成两行展示,但要算它们的差值,得把这两个值放在同一行里做减法才行。另外还要提个小问题:你用Salary regexp '[0]'来筛选0值其实不对,这个条件会匹配所有包含0的薪资(比如1000、205这些数都会被选中),直接用Salary = 0才是精准筛选薪资为0的行。
给你两种解决方案,按需选择:
方案一:子查询分别计算后相减
这种写法逻辑清晰,容易理解:
SELECT (SELECT AVG(Salary) FROM Employees WHERE Salary = 0) AS Salary_with0, (SELECT AVG(Salary) FROM Employees WHERE Salary != 0) AS Salary_without0, -- 这里用不带0的平均值减去带0的,你可以根据需求调整差值的正负方向 (SELECT AVG(Salary) FROM Employees WHERE Salary != 0) - (SELECT AVG(Salary) FROM Employees WHERE Salary = 0) AS Salary_diff FROM DUAL; -- DUAL是很多数据库(比如MySQL、Oracle)里的虚拟表,用来承载这种不需要从实际表取数据的查询;如果是SQL Server,直接省略FROM DUAL就行
方案二:一次扫描表完成计算(更高效)
如果你的Employees表数据量很大,多次扫描表会影响性能,那可以用CASE语句在一次扫描中计算两个平均值,然后直接相减:
SELECT AVG(CASE WHEN Salary = 0 THEN Salary END) AS Salary_with0, AVG(CASE WHEN Salary != 0 THEN Salary END) AS Salary_without0, AVG(CASE WHEN Salary != 0 THEN Salary END) - AVG(CASE WHEN Salary = 0 THEN Salary END) AS Salary_diff FROM Employees;
原理是:CASE语句会只保留符合条件的薪资值,不符合的返回NULL,而AVG函数会自动忽略NULL值,这样就能一次算出两个场景下的平均值,再直接做减法得到差值,效率比多次扫描表高很多。
内容的提问来源于stack exchange,提问作者Dhruv Dev
相关产品推荐
相关产品推荐

