2015-08-31 47 views

回答

0

在內部查詢中,您可以選擇列的最大長度並在外部查詢中將其消除,然後執行max,以便獲得該列中的第二大長度。

select max(val) as secondlargest 
from t join 
(
SELECT max(len(val)) as lf1 
FROM t 
) x 
on len(t.val) < x.lf1 

如果您需要所有長度第二大的值,最好使用cte s。 SQL Fiddle

with top2 as (
select top 2 len(val) as lf1 
from t 
order by len(val) desc 
) , 
scnd as 
(select min(lf1) as snd from top2) 
select val 
from t join scnd 
on len(t.val) = scnd.snd 
+0

vkp,max(val)不處理長度。它應該是max(len(val))不是嗎? – ElenaDBA

+0

@ ElenaDBA ..在第一個查詢中,第二個最大長度只能得到一個「val」。但是,使用'cte'的第二個查詢將爲您提供第二個最大長度的所有值。 –

3

的SQL Server 2012+支持OFFSET/FETCH

select len(f1) 
from table1 
group by len(f1) 
order by len(f1) desc 
offset 1 
fetch first 1 row only; 

在早期版本也有不同的方法。這裏是一個:

with ml as (
     select len(f1) as lenf 
     from table1 
     group by len(f1) 
    ) 
select max(lenf) 
from ml 
where lenf < (select max(lenf) from ml); 
+0

,它給了我「錯誤的語法靠近'抵消'」 – ElenaDBA

+0

然後推測你正在使用早期版本的SQL Server。 –

+0

我正在使用Azure SQL並通過Management Studio 2014 – ElenaDBA

0

如果你只需要第二個:

SELECT MAX(Field1) FROM Table1 
WHERE Field1 NOT IN (SELECT MAX(Field1) FROM Table1) 

請注意,這是唯一正確的,當兩個極大值是不一樣的。如果他們是,第二個答案仍然會被選中。例如:

1: 500 points 
2: 500 points 
3: 410 points 

2將仍然被選中,但它是有爭議的,你需要哪個答案。

1

窗口功能通常是最有效的方法來做到這一點,它們最終是靈活的,以適應不同的要求。下面是一個例子(Azure上的SQL數據庫進行測試):

select f1, lenf, lenf_dense_rank 
from (
     SELECT 
      f1, 
      lenf=len(f1), 
      lenf_dense_rank=dense_rank() over (order by len(f1) desc) 
     FROM table1 
) x 
where lenf_dense_rank = 2 

此外,根據您的需求,您可能需要使用rank()dense_rank(),但窗口功能仍然使用了這樣的情況的技術。強烈建議查找它們並更多地瞭解它們 - 應該比目前更頻繁地使用它們。

+0

順便說一句,通過說「通常更高效」,我的意思是你正在做1次全表掃描(或索引掃描),而自連接,並且在同一個表上使用max和子查詢,需要至少2相同類型的掃描 - 數據庫管理系統完成的相關工作量不應忽視!使用OFFSET/FETCH組合確實有效,但窗口函數可以做得更多,現在得到了廣泛的支持,所以我必須儘可能地推薦它們。 – SlimsGhost

相關問題