可能性のある複製:
最大値を含むテーブルのレコードを取得する方法
次のような集計クエリがあります。
SELECT TrainingID, Max(CompletedDate) as CompletedDate, Max(Notes) as Notes --This will only return the longest notes entry
FROM HR_EmployeeTrainings ET
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID)
GROUP BY AvantiRecID, TrainingID
これは動作しており、ほとんどの場合正しいデータを返しますが、問題に気づきました。返されるNotesフィールドは、max(completedDate)が由来するレコードと必ずしも一致しません。代わりに、文字列が最も長いものになりますか?または、最も高いASCII値?2つのレコードが同点になった場合にSQL Serverは何をしますか?確信が持てません。取得したいのはノートフィールドですmax(completedDate)レコード。これを行うにはどうすればよいですか?
サブクエリを使用できます。サブクエリはMax(CompletedDate)
を取得します。次に、この値を取得してテーブルに再度結合し、その日付に関連付けられているメモを取得します。
select ET1.TrainingID,
ET1.CompletedDate,
ET1.Notes
from HR_EmployeeTrainings ET1
inner join
(
select Max(CompletedDate) CompletedDate, TrainingID
from HR_EmployeeTrainings
--where AvantiRecID IS NULL OR AvantiRecID = @avantiRecID
group by TrainingID
) ET2
on ET1.TrainingID = ET2.TrainingID
and ET1.CompletedDate = ET2.CompletedDate
where ET1.AvantiRecID IS NULL OR ET1.AvantiRecID = @avantiRecID
そうです、それがSQLでの意図です。各列の最大値を個別に取得します。最大日付の行から値を返したいようですので、最大日付の行を選択する必要があります。クエリはコンパクトで読みやすいので、サブセレクトでこれを行うことを好みます。
SELECT TrainingID, CompletedDate, Notes
FROM HR_EmployeeTrainings ET
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID)
AND CompletedDate in
(Select Max(CompletedDate) from HR_EmployeeTrainings B
where B.TrainingID = ET.TrainingID)
AntiRecIDで照合する場合も、サブセレクトに含める必要があります。
これを行う簡単な方法はありませんが、次のように機能します。
SELECT ET.TrainingID,
ET.CompletedDate,
ET.Notes
FROM
HR_EmployeeTrainings ET
inner join
(
select TrainingID, Max(CompletedDate) as CompletedDate
FROM HR_EmployeeTrainings
WHERE (ET.AvantiRecID IS NULL OR ET.AvantiRecID = @avantiRecID)
GROUP BY AvantiRecID, TrainingID
) ET2
on ET.TrainingID = ET2.TrainingID
and ET.CompletedDate = ET2.CompletedDate
各MAX関数は個別に評価されます。そのため、MAX(CompletedDate)は最新のCompletedDate列の値を返し、MAX(Notes)は最大値(アルファベット順で最高)を返します。
必要なものを取得するには、クエリを異なる構造にする必要があります。この質問は、実際にすでに何度も尋ねられて答えられていたので、繰り返しません。