SQL 问题 - 如何让员工拥有与特定员工相同的技能
SQL question - How to get employees with the same skills as a specific employee
我有一个名为 Employee
的 table,其列为:
- EMPID INT(主键)
- EMPNAME VARCHAR2(100)
样本数据如下:
empid|empname|
-----|-------|
1|Mary |
2|Bob |
我有另一个 table Employee_Skills
列:
- EMPID INT
- 技能 VARCHAR2(100)
其中的一个样本可以表示如下:
empid|skill |
-----|------|
1|SKILL |
1|Java |
1|C++ |
1|Python|
2|C++ |
2|Python|
在第二个table中,两列共同构成了主键。 EMPID
有一个指向 Employee(EMPID)
.
的引用约束
我希望所有员工都具备 Mary 所拥有的所有技能。
例如,
select t2.skill
from Employee t1
join Employee_Skills t2 on (t1.EMPID = t2.EMPID)
where t1.EMPNAME = 'Mary'
此查询返回了这些行:
SKILL
------------
Java
C++
Python
... (a few more)
现在我想 select 所有具备上述技能的员工(可以有更多的技能,但至少应该有 Mary 拥有的技能)。
我已经做了几次尝试,但没有任何东西能满足我的需求。
这是一种失败的尝试:
select t1.EMPID, t1.EMPNAME
from Employees t1
join Employee_Skills t2 on (t1.EMPID = t2.EMPID)
where t2.SKILL = ALL (select t4.skill
from Employee t3
join Employee_Skills t4 on (t3.EMPID = t4.EMPID)
where t3.EMPNAME = 'Mary');
你可以用连接和聚合解决这个关系划分问题:
select e2.empid
from employee e1
inner join employee_skills es1 on es1.empid = e1.empid
inner join employee_skills es2 on es2.skill = es1.skill and es2.empid <> es1.empid
inner join employee e2 on e2.empid = es2.empid
where e1.empname = 'Mary'
group by e2.empid
having count(*) = (
select count(*)
from employee e3
inner join employee_skills es3 on es3.empid = e3.empid
where e3.empname = 'Mary'
)
有很多方法可以解决这个问题,其中最直观的一种可能是以下方法:
select emp.empid, emp.empname
from Employee_Skills esk
inner join employee emp
on emp.empid = esk.empid
where emp.empname <> 'Mary'
and exists (select null
from employee_skills esk_
inner join employee emp_
on emp_.empid = esk_.empid
where emp_.empname = 'Mary'
and esk_.skill = esk.skill);
PS: 我从返回的列表中排除了 Mary。
我重新创建了你的数据如下:
create table employee(EMPID INT , EMPNAME VARCHAR(100));
create table Employee_Skills(EMPID INT, SKILL VARCHAR(100));
insert into employee values (1, 'Mary');
insert into employee values (2, 'Bob');
insert into employee_skills values (2, 'SKILL');
insert into employee_skills values (2, 'Java');
insert into employee_skills values (1, 'C++');
insert into employee_skills values (1, 'Python');
insert into employee_skills values (2, 'C++');
insert into employee_skills values (2, 'Python');
这成功了。分享给大家。基本上,你会掌握玛丽的技能。减去当前员工的技能。如果你得到一个空白,你就会在结果中显示这个员工。
Select t4.empid, t4.empname from employee t4
Where not exists
(Select t1.skill from employee_skills t1 join employee t2 on (t1.empid = t2.empid) where t2.empname = 'Mary'
Minus
Select t3.skill from employee_skills t3 where t3.empid = t4.empid)
and t4.empname <> 'Mary';
我有一个名为 Employee
的 table,其列为:
- EMPID INT(主键)
- EMPNAME VARCHAR2(100)
样本数据如下:
empid|empname|
-----|-------|
1|Mary |
2|Bob |
我有另一个 table Employee_Skills
列:
- EMPID INT
- 技能 VARCHAR2(100)
其中的一个样本可以表示如下:
empid|skill |
-----|------|
1|SKILL |
1|Java |
1|C++ |
1|Python|
2|C++ |
2|Python|
在第二个table中,两列共同构成了主键。 EMPID
有一个指向 Employee(EMPID)
.
我希望所有员工都具备 Mary 所拥有的所有技能。
例如,
select t2.skill
from Employee t1
join Employee_Skills t2 on (t1.EMPID = t2.EMPID)
where t1.EMPNAME = 'Mary'
此查询返回了这些行:
SKILL
------------
Java
C++
Python
... (a few more)
现在我想 select 所有具备上述技能的员工(可以有更多的技能,但至少应该有 Mary 拥有的技能)。
我已经做了几次尝试,但没有任何东西能满足我的需求。
这是一种失败的尝试:
select t1.EMPID, t1.EMPNAME
from Employees t1
join Employee_Skills t2 on (t1.EMPID = t2.EMPID)
where t2.SKILL = ALL (select t4.skill
from Employee t3
join Employee_Skills t4 on (t3.EMPID = t4.EMPID)
where t3.EMPNAME = 'Mary');
你可以用连接和聚合解决这个关系划分问题:
select e2.empid
from employee e1
inner join employee_skills es1 on es1.empid = e1.empid
inner join employee_skills es2 on es2.skill = es1.skill and es2.empid <> es1.empid
inner join employee e2 on e2.empid = es2.empid
where e1.empname = 'Mary'
group by e2.empid
having count(*) = (
select count(*)
from employee e3
inner join employee_skills es3 on es3.empid = e3.empid
where e3.empname = 'Mary'
)
有很多方法可以解决这个问题,其中最直观的一种可能是以下方法:
select emp.empid, emp.empname
from Employee_Skills esk
inner join employee emp
on emp.empid = esk.empid
where emp.empname <> 'Mary'
and exists (select null
from employee_skills esk_
inner join employee emp_
on emp_.empid = esk_.empid
where emp_.empname = 'Mary'
and esk_.skill = esk.skill);
PS: 我从返回的列表中排除了 Mary。
我重新创建了你的数据如下:
create table employee(EMPID INT , EMPNAME VARCHAR(100));
create table Employee_Skills(EMPID INT, SKILL VARCHAR(100));
insert into employee values (1, 'Mary');
insert into employee values (2, 'Bob');
insert into employee_skills values (2, 'SKILL');
insert into employee_skills values (2, 'Java');
insert into employee_skills values (1, 'C++');
insert into employee_skills values (1, 'Python');
insert into employee_skills values (2, 'C++');
insert into employee_skills values (2, 'Python');
这成功了。分享给大家。基本上,你会掌握玛丽的技能。减去当前员工的技能。如果你得到一个空白,你就会在结果中显示这个员工。
Select t4.empid, t4.empname from employee t4
Where not exists
(Select t1.skill from employee_skills t1 join employee t2 on (t1.empid = t2.empid) where t2.empname = 'Mary'
Minus
Select t3.skill from employee_skills t3 where t3.empid = t4.empid)
and t4.empname <> 'Mary';