由于您尚未发布数据库结构,因此我做了一些假设和简化(关于rating列,可能是数字而不是字符字段).相应调整.
select distinct e.EmployeeId, e.Name
from employee e
left join reviews r1 on e.EmployeeId = r1.EmployeeId and r1.rating = 'good'
left join reviews r2 on e.EmployeeId = r2.EmployeeId and r1.rating = 'bad'
where r1.ReviewId is not null --meaning there's at least one
and r2.ReviewId is null --meaning there's no bad review
Run Code Online (Sandbox Code Playgroud)
select e.EmployeeId, max(e.Name) Name
from employee e
left join reviews r on e.EmployeeId = r.EmployeeId
group by e.EmployeeId
having count(case r.rating when 'good' then 1 else null end) > 0
and count(case r.rating when 'bad' then 1 else null end) = 0
Run Code Online (Sandbox Code Playgroud)
这两种解决方案都是SQL ANSI兼容的,这意味着它们都可以使用完全支持SQL ANSI标准的任何RDBMS风格(大多数RDBMS都适用).
正如@onedaywhen指出的那样,代码在MS Access中不起作用(尚未经过测试,我相信他在该主题方面的专业知识).
但我有一个说法(这可能会让一些人感到不安):我几乎不认为MS Access是一个RDBMS.我过去曾与它合作过.一旦你继续前进(Oracle,SQL Server,Firebird,PostGreSQL,MySQL,你的名字),你永远不想回来.认真.
问题 - 基于B中不存在匹配的A侧返回行 - (没有"错误"评论的员工)描述了"反半连接".有很多种方法可以完成这种查询,至少有5种我在MS Sql 2005及更高版本中发现过.
我知道这个解决方案适用于MSSQL 2000及更高版本,并且是我在MS Sql 2005和2008中尝试过的5种方法中效率最高的.我不确定它是否可以在MySQL中运行,但它应该,因为它反映了一个相当常见的集合操作.
注意,该IN子句为子查询提供了employee对外部作用域中表的访问.
SELECT EE.*
FROM employee EE
WHERE
EE.EmpKey IN (
SELECT RR.EmpKey
FROM review RR
WHERE RR.EmpKey = EE.EmpKey
AND RR.ScoreCategory = 'good'
)
AND
EE.EmpKey NOT IN (
SELECT RR.EmpKey
FROM review RR
WHERE RR.EmpKey = EE.EmpKey
AND RR.ScoreCategory = 'bad'
)
Run Code Online (Sandbox Code Playgroud)