原題: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 的方法能夠好好記住!!