----- 题目有点长,也有点拗口!
背景:
先分享一下本次sql查询的业务背景,假设数据库中有一张员工表emp_info,表中含有员工编号(id),部门编号(dept_id),小组编号(group_id) ,小组绩效等级(prfm_group_grade )等主要字段,
id是唯一主键,
一个部门有多个小组dept_id:group_id(1:N),
不同的部门可能存在相同的小组编号(比如财务部和销售部都有一个编号为‘01’的小组,但这两条数据的主键id不同),现在需要统计每组由两个或者两个以上的
每组各小组可能评为A、B、C、D任意其中一个等级
现在要求查询出,小组中有两个以上被评为 “D”等级的人员信息(如果小组中只有一个‘D’则不显示)
分析:
所有查询的信息都在emp_info 表中,所以开头 select a.* from emp_info a
查询的人员的绩效等级(prfm_group_grade )一定是'D' 给定限制条件 where a.prfm_group_grade =‘D’
此外最重要的一个条件,按照小组分组统计(由于小组编号不是区分每组的唯一编号还需要加上部门编号,所以实际分组条件是group by a.dept_id,a.group_id),且统计绩效等级 为‘D’ 的人数>1(having count(id) > 1),问题的难点在于我们需要查询每条数据的信息不是查询统计后的结果信息,所以直接select a.* from emp_info a where a.prfm_group_grade =‘D’ group by a.dept_id,a.group_id having count(a.id) > 1肯定是要报错的!!!
其实我们可以采用exists 巧妙的表达分组统计条件exists(select 1 from emp_info b where b.dept_id =a.dept_id and a.group_id =b.group_id group by b.dept_id,b.group_id having count(b.id) > 1 ) 这样的sql 我测试了一边 发现还是没有完全过滤掉我所需要的结果 ,到底是哪里出错了呢,再仔细的分析了下sql、 发现exists 的子查询中我们只是将主查询的 dept_id,group_id 传递给子查询,但是 prfm_group_grade =‘D’ 的条件漏掉了,所以完整的sql如下:
select a.* from emp_info a where a.prfm_group_grade =‘D’ and exists(select 1 from emp_info b where b.prfm_group_grade =‘D’and b.dept_id =a.dept_id and a.group_id =b.group_id group by b.dept_id,b.group_id having count(b.id) > 1 )
总结:
对于复杂的sql,逐步简化,理清主干,正确并合理的表达每一个给定条件,在结合 查询结果分析 ,基本的查询就都能搞定了。
----技术有限如有不足,欢迎交流指正。