sql - 如何访问相关子查询中的列
问题描述
使用以下数据,我试图获取具有相同位置和部门的员工,其类型为经理,其工资等于其他员工的总和 sal 以及 emp id,因为 empid 是不相等的查询不返回任何结果也分组查询应该有超过 1 条记录所以结果不应该包括 Raghu 记录,而且我想要所有匹配记录的 emp id:
EMP_ID EMP_Name EMP_Loc EMP_Dept EMP_Sal Emp_type
1 Arjun Hyd Comp 1000 Manager
2 Ramesh Hyd Comp 500 Interim
3 Ragav Hyd Comp 300 Interim
4 Rajesh Hyd Comp 200 Interim
5 Raghu Hyd Comp 1000 Interim
select a.emp_dept , a.emp_loc ,a.emp_dept,b.emp_dept,a.emp_id,b.emp_id
from
(select sum(emp_sal) as sett,emp_loc,emp_dept,emp_id
from employee
where emp_type = 'Interim'
group by emp_loc,emp_dept,emp_id having count(emp_sal)>1
) a
inner join
(select emp_sal ,emp_loc,emp_dept,emp_id
from employee
where emp_type = 'Manager'
) b
on a.sett=b.emp_sal and a.emp_loc=b.emp_loc and a.emp_dept=b.emp_dept;
解决方案
您的问题是您将 emp_id 包含在您的第一个子选择中并对其进行分组。这意味着你得到三行,总和变得毫无意义。从来没有经理有 500、200 或 300 薪水的情况,因此连接不起作用,因此没有返回记录。如果你这样做,它应该工作:
select a.emp_dept, a.emp_loc, b.emp_id
from
(select sum(emp_sal) as sett,emp_loc,emp_dept
from employee
where emp_type = 'Interim' and emp_sal > 1
group by emp_loc,emp_dept
) a
inner join
(select emp_sal ,emp_loc,emp_dept,emp_id
from employee
where emp_type = 'Manager'
) b
on a.sett=b.emp_sal and a.emp_loc=b.emp_loc and a.emp_dept=b.emp_dept;
请注意,我还删除了结果集中的重复列。显示 b.emp_dept 和 a.emp_dept 是没有意义的,因为连接条件保证它们是相同的。
编辑
在您对问题进行修改后,我现在了解您要做什么。这真的很难实现,因为您需要做的是对一个地点和部门的所有可能的临时工资进行笛卡尔总和,以检查工资总和的任何可能组合是否与经理的组合匹配。
一种可能的方法是:
WITH cte as
(SELECT a.emp_id as aempid, b.emp_id as bempid, 0 as cempid, 0 as dempid, a.emp_sal + b.emp_sal AS SumSal, a.emp_loc, a.emp_dept
FROM employee a
CROSS JOIN employee b WHERE a.emp_loc = b.emp_loc AND a.emp_dept = b.emp_dept
AND a.emp_type = b.emp_type AND a.emp_type = 'Interim' AND a.emp_id <> b.emp_id
AND b.emp_id > a.emp_id
UNION
SELECT a.emp_id, b.emp_id, c.emp_id, 0, a.emp_sal + b.emp_sal + c.emp_sal AS SumSal, a.emp_loc, a.emp_dept
FROM employee a
CROSS JOIN employee b
CROSS JOIN employee c
WHERE a.emp_loc = b.emp_loc AND a.emp_dept = b.emp_dept
AND a.emp_type = b.emp_type AND a.emp_type = 'Interim' AND a.emp_id <> b.emp_id
AND a.emp_loc = c.emp_loc AND a.emp_dept = c.emp_dept
AND a.emp_type = c.emp_type AND a.emp_id <> c.emp_id AND b.emp_id <> c.emp_id
AND b.emp_id > a.emp_id AND c.emp_id > b.emp_id
UNION
SELECT a.emp_id, b.emp_id, c.emp_id, d.emp_id, a.emp_sal + b.emp_sal + c.emp_sal + d.emp_sal AS SumSal, a.emp_loc, a.emp_dept
FROM employee a
CROSS JOIN employee b
CROSS JOIN employee c
CROSS JOIN employee d
WHERE a.emp_loc = b.emp_loc AND a.emp_dept = b.emp_dept
AND a.emp_type = b.emp_type AND a.emp_type = 'Interim' AND a.emp_id <> b.emp_id
AND a.emp_loc = c.emp_loc AND a.emp_dept = c.emp_dept
AND a.emp_type = c.emp_type AND a.emp_id <> c.emp_id AND b.emp_id <> c.emp_id
AND a.emp_loc = d.emp_loc AND a.emp_dept = d.emp_dept
AND a.emp_type = d.emp_type AND a.emp_id <> d.emp_id AND b.emp_id <> d.emp_id AND c.emp_id <> d.emp_id
AND b.emp_id > a.emp_id AND c.emp_id > b.emp_id AND d.emp_id > c.emp_id
)
SELECT m.emp_id as managerid, cte.aempid, cte.bempid, cte.cempid, cte.dempid, m.emp_sal, m.emp_loc, m.emp_dept
FROM employee m
INNER JOIN cte ON cte.emp_loc = m.emp_loc AND cte.emp_dept = m.emp_dept AND m.emp_sal = cte.sumsal
WHERE m.emp_type = 'Manager';
这真的很难看,但我想不出更好的了,至少它返回了预期的结果。当然,在实践中,您必须动态创建它以匹配任何一个地点/部门的临时员工的最大数量。
几点,以防不清楚。使用这种方法不需要 a,HAVING COUNT(*) > 1
因为要求 a.emp_id <> b.emp_id 等保证至少有两个不同的临时雇员。还要求 b.emp_id > a.emp_id(以及 c 和 d)以确保 a、b、c 和 d 的每个可能组合只出现一次(所以在这种情况下,我们只得到 2、3、4(按此顺序)加上 0 表示 d,而不是 2、3 和 4 的所有可能组合。
推荐阅读
- php - 使用 PDO 从 PostgreSQL 表中获取结果时遇到问题
- c# - LinqToExcel - 从 *.xlsx 文件中读取小数
- c# - 实体框架到 MySql 连接到数据库失败
- lua - 将子表分配给 Lua 中的未知索引
- c - 如何检查某些关键字/属性的编译器支持?
- elasticsearch - 在 ElasticSearch 中查询格式错误的空子句错误
- android - Android Studio 3.1.2 gradle 构建错误
- python - 来自输入的列表中项
- vb.net - dgv 属性更改时出现 NullReferenceException
- python - numpy 按索引求和矩阵行