每一个部门绩效成绩第二名 sql server 查询 ( 替代 not in )

原题:sql

集团中有多个部门,部门底下有多个员工,求每一个部门绩效分数排名第二的人员,数据表结构以下:spa

  DEPAR          NAME             SCORE.net

       A                   A1                  66code

       A                   A2                  80blog

       A                   A3                  55class

       B                   B3                  36百度

       B                   B3                  78select

       C                   C3                  57bug

       C                   C3                  92方法

 

 

这是某公司笔试题,朋友问个人时候,我以为挺好玩,而后直接就顺着思路写出来答案,

首先把各部门第一名排除掉,那么在求业绩的max就是每一个部门的第二名,sql以下:

 

 

SELECT MAX([SCORE]) AS DSECOND,DEPAR FROM [DEPARSCORE]
 WHERE [SCORE] NOT IN 
(
(SELECT MAX([SCORE])
  FROM [DEPARSCORE] group by depar)
)
GROUP BY DEPAR

查询结果,ok,棒极了

 

但是朋友说好像有哪里不对,我又试了试把数据改为了这样

再次查询试试

那么B的第二名去哪里了,这条sql确实是有bug的,可是错在哪里了,

我分析了一下,我以为是 WHERE [SCORE] NOT IN 出的问题,

首先查询各部门第一名结果以下:

A80,B90,C20,而后SCORE NOT IN 获得的应该是

A66,A55,C20

问题就出来了,B部门的第二名去哪了呢,缘由是SCORE NOT IN (80,90,20),那B部门的第二名固然就出不来了啊。

由于B的第二名分数正好等于A的第一名的分数,咱们判断分数不等于A的第一名,那同时也不等于B的第二名。

因此说单纯的判断分数不等于以外还要加上部门判断,那怎么判断呢:

我决定这样

SELECT MAX([SCORE]) AS DSECOND,DEPAR FROM [DEPARSCORE]
 WHERE [SCORE] NOT IN 
(
(SELECT MAX([SCORE],DEPAR)
  FROM [DEPARSCORE] group by depar) AS B
) AND [DEPARSCORE].DEPAR=B.DEPAR
GROUP BY DEPAR

哈哈,很明显不对,由于not in不可能跟着两个字段啊

消息 116,级别 16,状态 1,第 6 行
当没有用 EXISTS 引入子查询时,在选择列表中只能指定一个表达式。

我很头疼,若是不用not in ,我想不出来如何作,试着百度了一下not in 发现一片文章能够替代not in,

我就试试

http://blog.csdn.net/shenyisyn/article/details/544694

 

因而就有了这段sql

 

select aa.*,bb.DSECOND as tempcolum from 
(SELECT [SCORE],DEPAR FROM [DEPARSCORE]) as aa
 left join (SELECT MAX([SCORE]) AS DSECOND,DEPAR
  FROM [membdatabases_bak].[dbo].[DEPARSCORE] group by depar )as bb on aa.[SCORE]=bb.DSECOND
  and aa.DEPAR=bb.DEPAR

结果以下

这时候能够看出来,除了第一名以外的全部列tempcolum都为null

而后以tempcolum is null为条件查出来

 

获得了各部门除第一名以外的全部数据

而后

select MAX(SCORE),DEPAR from (
select aa.*,bb.DSECOND as tempcolum from 
(SELECT [SCORE],DEPAR FROM [DEPARSCORE]) as aa
 left join (SELECT MAX([SCORE]) AS DSECOND,DEPAR
  FROM [membdatabases_bak].[dbo].[DEPARSCORE] group by depar )as bb on aa.[SCORE]=bb.DSECOND
  and aa.DEPAR=bb.DEPAR) as dd where tempcolum is null
  
  GROUP BY DEPAR

 

而后就成功了

 

好嗨森,哈哈,今天没辜负。哈哈

这种替代not in 的方法能够好好记住!!

相关文章
相关标签/搜索