各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)
しかし、これが最善の方法であり、唯一の方法ですか?必要がなければサブクエリを使用するのは好きではありません。何かを使用できることを思い出しますが、それが何であるかを忘れています。何か案が?
SQL-Server(> = 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
結果セットのパーティション内の行の連番を返します。
編集:ここに表示されているようにOracleでも機能します: http://sqlfiddle.com/#!4/b7e79/2/
一般に、ウィンドウ関数またはランク付け関数(Rank()
、Row_number()
など)を使用する必要があります。
select *
from
(
select *, row_number() over (partition by id order by age desc) rn
from yourtable
) v
where rn = 1
これはSQLServer 2005+で機能します。Oracleでは、*
の代わりにフィールド名を明示的に指定する必要がある場合があります。
ウィンドウ関数をサポートしないRDBMSを使用する場合に備えて、次のものを使用できます。
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
それでもサブクエリが含まれますが、サブクエリなしでこれを行う方法はわかりません。また、サブクエリを避けたい理由もわかりません。