Я использую один и тот же шаблон SQL снова и снова, и я знаю, что должен быть лучший способ, но у меня проблемы собирать все вместе. Вот простая версия шаблона, в которой я извлекаю информацию об учащемся и последнюю книгу, которую они прочитали, если таковая существует:
SELECT TStudents.*,
BookName = (SELECT TOP 1 BookName
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC),
BookAuthor = (SELECT TOP 1 BookAuthor
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC),
BookCheckout = (SELECT TOP 1 DateCheckedOut
FROM TBookCheckouts
WHERE StudentID = TStudents.ID
ORDER BY DateCheckedOut DESC)
FROM TStudents
(Для этого примера, пожалуйста, игнорируйте тот факт, что TBookCheckouts, вероятно, следует разделить в TCheckouts и TBooks)
То, что я пытаюсь проиллюстрировать: у меня есть много подзапросов для столбцов из одной и той же таблицы. Я также склонен отсортировать эти подчиненные таблицы по дате, чтобы получить самую последнюю запись, поэтому это не так просто (по крайней мере, для меня), как выполнение LEFT JOIN. Однако обратите внимание, что, за исключением того, какое поле возвращается, я, по сути, выполняю один и тот же подзапрос 3 раза. SQL Server может быть достаточно умен, чтобы оптимизировать это, но я думаю, что нет (мне определенно нужно научиться лучше читать планы выполнения ...).
Хотя такое структурирование может иметь преимущества (иногда это заканчивается будучи более читабельным, если у меня есть тонны подзапросов и подтаблиц), это не кажется особенно эффективным.
Я рассмотрел возможность выполнения LEFT JOIN из производной таблицы, возможно, включая ROW_NUMBER () и PARTITION BY, но я просто не могу собрать все воедино.