2012-10-31 42 views
8

我想只選擇最高SEQ行每個ID如何僅使用最大序列選擇行而不使用子查詢?

ID | Seq | Age 
------------------- 
A  1  20 
A  2  30 
B  1  25 
B  2  32 
B  3  44 
B  4  48 
C  1  11 

這似乎工作

SELECT ID, Age 
FROM Persons a 
WHERE Seq = (SELECT MAX(Seq) FROM Persons b WHERE a.ID = b.ID) 

但是,這是最好的辦法,唯一的辦法?我不喜歡使用子查詢,如果我不需要,我記得你可以使用一些東西,但我忘記它是什麼。任何想法?

+0

您正在使用什麼RDBMS? –

+0

主要的SQL Server,但如果它是與Oracle兼容那麼這真棒 – jenswirf

+0

我'ROW_NUMBER'方法效果也是甲骨文,因爲我已經有了SQL-小提琴測試。看看我的答案中的鏈接。 –

回答

5

假設SQL - 服務器(> = 2005)或Oracle(10克):

WITH CTE AS 
( 
    SELECT 
     ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Seq DESC) AS RN 
     , ID, Age 
    FROM 
     Persons 
) 
SELECT ID, Age 
FROM CTE 
WHERE RN = 1 

ROW_NUMBER返回結果集的一個分區內的行的順序號。

編輯:工作也在甲骨文,你可以在這裏看到:http://sqlfiddle.com/#!4/b7e79/2/0

+0

感謝您刷新我的大腦,我在過去使用它,並在很長一段時間後使用它,它完美的工作! – superachu

1

一般情況下,你neeed使用窗口或排名函數 - Rank()Row_number()

select * 
from 
(
    select *, row_number() over (partition by id order by age desc) rn 
    from yourtable 
) v 
where rn = 1 

這將在SQL Server 2005+的工作 - 在Oracle中,你可能需要代替*

+0

這是我可以想到的最好的方式。但是,它有兩個選擇子句,如果你不喜歡這個,你可以採取內部選擇,並在你的應用程序中看到沒有排在第一位的所有東西;) – OzrenTkalcecKrznaric

1

物權法明確指定字段名稱,如果你使用的是不支持窗口功能的RDBMS T,你可以使用:

SELECT Persons.ID, Persons.Age, Persons.Seq 
FROM Persons 
     INNER JOIN 
     ( SELECT Persons.ID, MAX(Seq) AS Seq 
      FROM Persons 
      GROUP BY Persons.ID 
     ) MaxP 
      ON MaxP.ID = Persons.ID 
      AND MaxP.Seq = Persons.Seq 

它還涉及到一個子查詢,但我不認爲這樣做沒有一個的方式,也不是我真的理解你爲什麼想要避開它們。

相關問題