Это хорошее применение для функций окна ранжирования .
Предположим, вы определили T_Subject
более или менее, как у вас уже есть:
SELECT StudentID,
MAX(Created) AS [Created],
'Whatever' AS [Subject Name]
FROM T_Student_Whatever
GROUP BY StudentID
UNION ALL
SELECT ... and so on for each T_Student_Foo...
Затем вы можете получить самую последнюю регистрацию по предмету (вы называете это "Последняя запись студента")на StudentID с:
SELECT StudentID,
Created,
[Subject Name]
FROM (SELECT T_Subjects.*,
ROW_NUMBER() OVER (PARTITION BY StudentID ORDER BY Created DESC)
AS [ranking] -- rank subject enrollment by recency
FROM T_Subjects)
WHERE ranking = 1 -- now select only the first ranked per StudentID
И затем вы можете присоединить этот запрос к вашей таблице T_Students
, чтобы получить имена и номера мобильных телефонов и т. д.
Обновление 2011-10-20
Не совсем понятно, что ищет ОП, но предпочтительнее может быть RANK()
, а не ROW_NUMBER()
.Первый из них будет дублировать ранжирование по эквивалентным характеристикам разделов, то есть записи могут «связывать» N-е место.
Например, если предположить, что ученик с идентификатором # 1 последний раз вчера принимал и Computing, и History, но ученик #2 самое последнее время, когда компьютер занимался вычислениями две недели назад, разница будет:
[ RANK()d ]
StudentID | StudentLastEntry | SubjectName
-----------+------------------+-------------
1 | 2011-10-19 | Computing
1 | 2011-10-19 | History
2 | 2011-10-06 | Computing
против, например,
[ ROW_NUMBER()d ]
StudentID | StudentLastEntry | SubjectName
-----------+------------------+-------------
1 | 2011-10-19 | History -- or 'Computing'
2 | 2011-10-06 | Computing