2013-12-19 62 views
0

我得到第11屆老年人從用戶表下面的SQL語句如何獲得第N個大項

select MAX(age) 
from (select * 
     from (select * 
      from users 
      order by age asc) 
     where rownum <12) 

有一個簡化和高效的查詢來獲取十一老年人提供全面的資料?

使用 甲骨文11G

+0

http://stackoverflow.com/questions/7417415/how-to-get-second-highest-salary-employees-in-a-table – Damodaran

+1

你能標記你正在使用的rdbms嗎? –

+0

我的數據庫是oracle 11g –

回答

2
WITH AgeOrderedPersons AS (
    SELECT usr.* 
      ,ROW_NUMBER() OVER (ORDER BY Age) AS Number 
    FROM Users usr 
) 
SELECT * 
FROM AgeOrderedPersons 
WHERE Number = 11 

如果你想與同年齡段使用DENSE_RANK()代替ROW_NUMBER()

+1

它不是那麼高效,我比較了你的和我的sql語句。我的SQL比你的性能差不多三倍。 –

0

SQL Fiddle

的Oracle 11g R2架構設置所有用戶:

CREATE TABLE users (age, x) AS 
      SELECT 20, 1 FROM DUAL 
UNION ALL SELECT 80, 2 FROM DUAL 
UNION ALL SELECT 47, 3 FROM DUAL 
UNION ALL SELECT 33, 4 FROM DUAL 
UNION ALL SELECT 24, 5 FROM DUAL 
UNION ALL SELECT 7, 6 FROM DUAL 
UNION ALL SELECT 102, 7 FROM DUAL 
UNION ALL SELECT 99, 8 FROM DUAL 
UNION ALL SELECT 90, 9 FROM DUAL 
UNION ALL SELECT 28, 10 FROM DUAL 
UNION ALL SELECT 46, 11 FROM DUAL 
UNION ALL SELECT 54, 12 FROM DUAL 
UNION ALL SELECT 67, 13 FROM DUAL 
UNION ALL SELECT 17, 14 FROM DUAL 
UNION ALL SELECT 34, 15 FROM DUAL 
UNION ALL SELECT 32, 16 FROM DUAL 
UNION ALL SELECT 39, 17 FROM DUAL 
UNION ALL SELECT 26, 18 FROM DUAL 
UNION ALL SELECT 15, 19 FROM DUAL 
UNION ALL SELECT 12, 20 FROM DUAL; 

查詢1

SELECT DISTINCT 
     NTH_VALUE(age, 11) IGNORE NULLS OVER (ORDER BY age ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS age, 
     NTH_VALUE(x, 11) IGNORE NULLS OVER (ORDER BY age ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS x 
FROM users 

Results

| AGE | X | 
|-----|----| 
| 34 | 15 | 

查詢2

包括在語句ROW_NUMBER()排序子句:

WITH ranked AS (
    SELECT u.*, 
     ROW_NUMBER() OVER (ORDER BY age) AS rn 
    FROM users u 
    ORDER BY age 
) 
SELECT age, x 
FROM ranked 
WHERE rn = 11 

Results

| AGE | X | 
|-----|----| 
| 34 | 15 | 

查詢3

WITH ordered AS (
    SELECT * 
    FROM users 
    ORDER BY age 
), 
ranked AS (
    SELECT o.*, 
     ROWNUM AS rn 
    FROM ordered o 
    WHERE ROWNUM <= 11 
) 
SELECT age, x 
FROM ranked 
WHERE rn = 11 

Results

| AGE | X | 
|-----|----| 
| 34 | 15 |