2017-10-06 64 views
0

我想第二個薪水最高形式此查詢SELECT * FROM c其中薪水(從C爲了通過薪金降序組由ROWNUM薪水具有選擇薪水的rownum = 2);

SELECT * 
FROM c 
WHERE salary IN (
     SELECT salary 
     FROM c 
     ORDER BY salary DESC 
     GROUP BY rownum salary 
     HAVING rownum = 2 
     ); 

Error: Missing Expression

+0

哪裏是你的表名? –

+0

選擇* from c where salary in(選擇薪水從c order by salary desc group by rownum having rownum = 2);試試這個 –

+0

如果工資是10,10,9,8 ...,預期的結果是什麼?即一條領帶。 – jarlh

回答

2

你可以在這裏使用一個秩分析函數,例如

SELECT salary 
FROM 
(
    SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) dr 
    FROM c 
) t 
WHERE dr = 2; 

這將通過密集的排名回到第二高的薪水,包括所有的第二次關係。

+0

這是更好的解決方案,因爲您可以返回其他列。 –

0

解釋爲什麼你的子查詢不能工作:

  1. 起初,記錄從表中任意順序讀取。這是當他們得到他們的rownum
  2. 然後發生聚合;一個salary的所有記錄都會壓縮爲一行。您以前的單行的rownum不再可用。
  3. 然後彙總行由HAVING過濾,這可不行,因爲你是在試圖訪問rownum。此外,在rownum = 2條件總是失敗,因爲你解僱的第一行,所以它是「不讀」和rownum 1仍然是可用的,您關閉第二個,因爲你還沒有閱讀rownum 1着呢,等等。在rownum標準始終是rownum <= some_number(除1,你可以有rownum = 1)。
  4. 出現這種情況的最後一件事是排序;因此ORDER BY子句屬於查詢的末尾。 (它只能跟着FETCH FIRST n ROWS如Oracle 12c的。)

這裏是如何使它與rownum工作:

select salary 
from 
(
    select salary 
    from 
    (
    select distinct salary 
    from c 
    order by salary desc 
) 
    where rownum <= 2 
    order by salary 
) 
where rownum = 1; 

這工作,因爲Oracle在這裏違反SQL標準。根據該標準,來自子查詢的數據被認爲是無序的,但Oracle在使用rownum時保證了訂單。

這裏是如何與聚集做到這一點:

select max(salary) from c where salary < (select max(salary) from c); 

由於Oracle 10,你還可以使用分析函數如圖添的回答。