Хорошие решения уже опубликованы, но я решил опубликовать объяснение того, как шаг за шагом можно упростить ваш запрос:
Внешний подзапрос избыточен
Самая внешняя часть подзапроса (бит SELECT [Id] FROM [Post] WHERE [Id] IN (
) является избыточной, поскольку вы уже возвращаете список идентификаторов).
Это оставляет нас с
SELECT comment1.[Post_Id]
FROM (
SELECT max([CommentNumber]) as maxComment,
[Post_id]
FROM [Comment]
GROUP BY [Post_id]
) as comment2
INNER JOIN [Comment] as comment1 on comment1.[Post_id] = comment2.[Post_id]
WHERE comment1.[Timestamp] BETWEEN '2/1/2010 00:00:00.000' AND '2/28/2010 23:59:59.999'
AND comment1.[CommentNumber] = comment2.maxComment
Использование CommentNumber является избыточным
Нет необходимости использовать CommentNumber для получения самого последнего комментария, так как сообщения уже упорядочены по метке времени. Это означает, что вместо выбора метки времени комментария с самым высоким Id мы можем просто выбрать самую высокую метку времени.
Это устраняет необходимость присоединяться к комментариям снова, оставляя нам:
SELECT [Post_Id], SomeColumn, SomeOtherColumn
FROM (
SELECT max([TimeStamp]) as maxTimeStamp,
[Post_id],
SomeColumn,
SomeOtherColumn
FROM [Comment]
GROUP BY [Post_id]
) as GroupedComments
WHERE GroupedComments.maxTimeStamp BETWEEN '2/1/2010 00:00:00.000' AND '2/28/2010 23:59:59.999'
Подзапрос теперь избыточен
Теперь запрос несколько упрощен, и будет легко увидеть, как его можно сократить до одного из других решений, размещенных здесь с использованием синтаксиса distinct
или having
.
Используйте <и> = вместо МЕЖДУ
Просто маленький щелчок. Вместо того, чтобы переходить на большую дату, чтобы найти последнюю дату в феврале, разбиение BETWEEN на <и a> = делает запрос намного чище:
WHERE GroupedComments.maxTimeStamp >= '2/1/2010'
AND GroupedComments.maxTimeStamp < '3/01/2010'