如何基于同一列中的多个值过滤SQL查询

时间:2017-09-26 22:08:34

标签: sql-server tsql

我需要编写一个查询,只会将缺少学位的员工输入我们的ERP系统。例如,我们有一个列出其学位的表格。

Employee ID   FName  LName  Degree
100           John   Smith  BA
200           Bill   Jones  BS
300           Alice  Waters BA
300           Alice  Waters MA
400           Joe    Lewis  MA

他们希望我从这张桌子上拉出来,只有乔·刘易斯,因为他没有在系统中输入学士学位,但由于他拥有硕士学位,他的假设是他还有一个学士学位,而且只有一个人错过了进入系统。

我尝试过对Bachelors学位使用EXCEPT过滤,但仍然会产生

Employee ID   FName  LName  Degree
300           Alice  Waters MA
400           Joe    Lewis  MA

我不希望Alice在列表中,因为她有一个学士学位编码到系统中。

对我如何处理这个问题的任何想法都将非常感激。

3 个答案:

答案 0 :(得分:2)

如果仅适用于MA和BA,则可以使用条件聚合:

select empid, fname, lname
from t
group by empid, fname, lname
having sum(case when degree = 'BA' then 1 else 0 end) = 0 and
       sum(case when degree = 'MA' then 1 else 0 end) > 0;

或者,您可以使用exists

select t.*
from t
where degree = 'MA' and
      not exists (select 1
                  from t t2
                  where t2.empid = t.empid and t2.degree = 'BA'
                 );

答案 1 :(得分:1)

你可以使用Masters子集的左连接来对抗Bachelors子集:

select m.EmployeeId, m.FName, m.LName 
from      (select * from Employee where Degree in ('MA')) m
left join (select * from Employee where Degree in ('BA', 'BS')) b
on m.EmployeeId = b.EmployeeId
where b.EmployeeId is null

答案 2 :(得分:0)

也许您应该考虑使用查询不带子查询......

SELECT E.EmployeeId, E.FName, E.LName 
FROM Employee AS E
LEFT JOIN Employee AS F ON (E.EmployeeId = F.EmployeeId AND F.Degree = 'BA')
WHERE E.Degree <> 'BA' AND F.EmployeeId IS NULL

或(如果必须考虑BS):

SELECT E.EmployeeId, E.FName, E.LName 
FROM Employee AS E
LEFT JOIN Employee AS F ON (E.EmployeeId = F.EmployeeId AND F.Degree IN('BA','BS'))
WHERE E.Degree <> 'BA' AND E.Degree <> 'BS' AND F.EmployeeId IS NULL

请记住,子查询通常很慢,具体取决于涉及的行数...