1

次のような RESULTS というテーブルがあります。

RESULTS_IDN    NAME    SUBJECT    YEAR    QUALIFIED
1              MARK    ENGLISH    1989    N
3              MARK    ENGLISH    1991    N
5              MARK    ENGLISH    1993    Y
7              MARK    ENGLISH    1995    N
2              MARK    MATH       1990    N
5              MARK    MATH       1993    N
6              MARK    MATH       1995    Y
4              MARK    SCIENCE    1991    N
9              MARK    SCIENCE    1997    Y

彼が作成した最新の試験のサブジェクトの候補者の資格ステータスを知る必要があります。このクエリ (ORACLE/MSSQL) を作成するにはどうすればよいですか?

たとえば、入力

NAME,SUBJECT  OUTPUT NAME IDN SUBJECT YEAR Q
MARK,ENGLISH  OUTPUT MARK 7   ENGLISH 1995 N 
MARK SCIENCE  OUTPUT MARK 9   SCIENCE 1997 Y
MARK MATH     OUTPUT MARK 6   MATH    1995 Y

これを解決する 1 つの方法を知っています。

(SELECT NAME SUBJECT YEAR MAX(YEAR) YEAR
FROM RESULTS WHERE NAME = 'MARK' AND SUBJECT ='MATH'
GROUP BY NAME SUBJECT YEAR) LATEST 

上記のテーブルを IDN で同じテーブルに結合すると、結果を取得できます。しかし、これは二重の作業です。とにかく、MAX(YEAR) をクラブして、HAVING CLAUSE などを使用して対応する年を取得できますか? GROUP BY データに対する 2 つの操作、1 つの最新の操作、および対応する Qualified ステータスが必要です。

PS: もちろん DB にはこのような 100 人の候補のレコードがあります。

更新 : この質問は、 回答 2 のようにグループあたり最大 n の問題としても分類されます。DB で分類された問題であることを知るのは興味深いことです。

4

2 に答える 2

3

Oracle と SQL Server の両方で、分析/ウィンドウ関数 RANK() または ROW_NUMBER() を使用してこれを実現できます。

select *
  from ( select a.*
              , rank() over ( partition by name, subject order by year desc ) rnk
           from ... a
                )
 where rnk = 1

RANK() は最新の各行に対して 1 を返しnamesubjectROW_NUMBER() はランダムな行を返します。

Oracle だけでは、KEEPを使用して同じ結果を得ることができます。

select name, subject, max(year) as year
     , max(qualified) keep (dense_rank first order by year desc) as qualified
  from ...
 group by name, subject
于 2013-06-29T13:04:39.907 に答える