2009-07-13 85 views
4

一個相當複雜的SQL查詢我工作讓我思考(ANSI)SQL的限制:檢索最大/最小記錄

有沒有一種方法來檢索記錄是最大或最小相對於一任意排序?

換句話說:

鑑於這樣的查詢:

SELECT * FROM mytable WHERE <various conditions> ORDER BY <order clause> 

是有可能寫的是(通過變換順序條款到別的可能)只返回第一行查詢?

我知道你可以做到這一點使用LIMIT(MySQL的)/ ROWNUM(甲骨文)或類似的,但是這不是標準的SQL。我也知道你可以通過在子查詢中獲取你感興趣的最大/最小值(使用MIN()/ MAX())來做到這一點,然後在你的主要SELECT中使用該結果作爲標準,即:

SELECT * FROM mytable WHERE <various conditions> AND myMaxColumn=(
    SELECT MAX(myMaxColumn) FROM mytable WHERE <various conditions> 
) 

但是,這隻能如果我想通過一個單一的列進行排序。我沒有辦法將其推廣到多列(除了嵌套上述解決方案,但這意味着當由n個coluns排序時,會有2^n個SELECT)。

那麼,有沒有標準SQL更好的方式比嵌套多個子選擇?

一個相關的問題是Create a SQL query to retrieve most recent records問。然而,問題的答案有建議或者使用LIMIT &的朋友,或者使用子查詢與MAX()如上所述,這兩者是不是我的問題的解決方案。

+0

注意:剛剛發現了一個類似的問題:http://stackoverflow.com/questions/121387/fetch-the-row-which-has-the-max-value-for-a-column – sleske 2012-03-28 16:01:03

回答

10

SQL:2003定義的窗口功能,其中的一個概念:

SELECT * 
FROM (
     SELECT *, ROW_NUMBER() OVER (ORDER BY col1, col2, col3) AS rn 
     FROM mytable 
     ) q 
WHERE rn = 1 

將返回你這第一條記錄。

至於現在,它是由SQL ServerOracle以來Jul 01, 2009支持。但是,通過PostgreSQL 8.4

注意的是,ROW_NUMBER()Oracle比原生的方式效率較低,限制記錄(即ROWNUM)。

看到這篇文章在我的博客的性能對比:

SQL:2008提供了一個條款要做到這一點:

SELECT * 
FROM mytable 
ORDER BY 
     col1, col2, col3 
FETCH FIRST 1 ROW ONLY 

,但就目前而言,這個確切語法僅支持DB2AFAIK)。

+0

這適用於數據庫實施SQL2003標準。它在很多數據庫中都不被支持,包括MySQL和PostgreSQL。這絕對是編寫這種查詢類型的最簡單方法之一。 – LBushkin 2009-07-13 12:08:40

8

如果我理解正確的話,你,我想你正在尋找的OVER子句,可以用來分隔結果集,定義爲ANSI SQL 2003標準的一部分。

它在RDBMS平臺上的實現並不是很一致。