2012-10-31 2 views
8

나는 각 ID이하위 쿼리를 사용하지 않고 최대 시퀀스가있는 행만 선택하는 방법은 무엇입니까?

SELECT ID, Age 
FROM Persons a 
WHERE Seq = (SELECT MAX(Seq) FROM Persons b WHERE a.ID = b.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 

, 유일한 방법은 가장 높은 서열 만 행을 선택하기 위해 노력하고있어? 내가 할 필요가없는 서브 쿼리를 사용하는 것을 좋아하지 않는다. 나는 당신이 무언가를 사용할 수 있다고 회상하지만 그것이 무엇인지 잊는다. 어떤 생각?

+0

어떤 rdbms를 사용하고 있습니까? –

+0

주로 SQL 서버이지만, 오라클과 호환되면 멋지다. – jenswirf

+0

내'ROW_NUMBER' 접근 방식은 SQl-Fiddle으로 테스트 한 것처럼 오라클에서도 작동합니다. 내 대답에 링크를보십시오. –

답변

5

SQL-서버 (> = 2005) 또는 Oracle 가정 (10g을?) :

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는 결과 집합의 파티션 내에서 행의 일련 번호를 반환합니다. - 등

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

이 의지 Rank(), Row_number(), http://sqlfiddle.com/#!4/b7e79/2/0 일반적으로

+0

내 뇌를 상쾌하게 해줘서 고마워, 과거에 이것을 사용했고 오랜 시간이 지난 지금 사용하면 완벽하게 작동합니다! – superachu

1

, 당신은 윈도우 또는 순위 함수를 사용하는 neeed :

편집 : 당신은 여기에서 볼 수 있듯이 오라클도 작동 SQL Server 2005 이상에서 작동합니다. - oracle에서는 필드 이름을 명시 적으로 지정해야 할 수도 있습니다. 대신 *

+0

이것은 제가 생각할 수있는 최선의 방법입니다. 그러나, 거기에 두 개의 선택 조항이 있으며, 당신이 그걸 좋아하지 않는다면, 당신은 내부 선택을 받아서 앱에서 1 위가 아닌 모든 것을봤을 수 있습니다;) – OzrenTkalcecKrznaric

1

Jus

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 

그것은 여전히 ​​하위 쿼리를 포함,하지만 난 하나없이이 일을하는 방법을 볼 수 없습니다, 나 정말이야 : 당신이 윈도우 기능을 지원하지 않는 RDBMS를 사용하는 경우 t, 당신은 사용할 수 있습니다 왜 당신이 그들을 피하기를 원할지 이해하십시오.

관련 문제