Во-первых, ваш запрос плохо написан для потока читаемости / взаимосвязи таблиц. Я обновил и отступ, чтобы попытаться показать, как / где таблицы связаны в иерархической относительности.
Вы также хотите разбить на страницы, давайте вернемся к этому. Намереваетесь ли вы показать каждую запись в качестве возможного элемента, или вы намеревались показать набор данных «родительского» уровня ... Например, у вас есть только один экземпляр на носитель, на пользователя или что-то еще, затем, как только эта запись будет Вы выбрали бы показать детали для этого одного лица? если это так, я бы сделал запрос DISTINCT на верхнем уровне или, по крайней мере, взял бы несколько столбцов с количеством (*) дочерних записей, которые он должен показать на следующем уровне.
Кроме того, смешивание внутренних, левых и правых объединений может привести к путанице. Обычно правое объединение означает, что вам нужны записи из правой таблицы объединения. Можно ли это переписать так, чтобы все требуемые таблицы были слева, а необязательные - чтобы они оставались присоединенными ко вторичной таблице?
Разъяснение всех этих отношений определенно поможет вместе с контекстом, который вы пытаетесь выбрать из нумерации страниц. Я проверю комментарии, но, если они будут продолжительными, я отредактирую ваш исходный вопрос с дополнительными деталями и длинным комментарием.
Вот мой SOMEWHAT уточненный запрос, переписанный с учетом того, что, я думаю, отношения находятся в вашей базе данных. Обратите внимание на мои отступы, показывающие, где таблица A -> B -> C -> D для удобства чтения. Все это (ВНУТРЕННИЕ) СОЕДИНЕНИЯ, указывающие на то, что все они должны совпадать между всеми соответствующими таблицами. Если некоторые вещи НЕ всегда есть, они будут изменены на ЛЕВЫЕ СОЕДИНЕНИЯ
SELECT
*
FROM
KisiselCoach KC
JOIN WorkPlace WP
ON KC.KisiselCoachId = WP.WorkPlaceOwnerId
JOIN Album A
ON KC.KisiselCoachId = A.AlbumId
JOIN Media M
ON A.AlbumId = M.AlbumId
LEFT JOIN Rating R
ON KC.KisiselCoachId = R.OylananId
JOIN FrUser Fr
ON KC.CoachId = Fr.UserId
JOIN UserJob UJ
ON KC.KisiselCoachId = UJ.UserJobOwnerId
JOIN Job J
ON UJ.JobId = J.JobId
JOIN UserExpertise UserEx
ON KC.KisiselCoachId = UserEx.UserExpertiseOwnerId
JOIN Expertise Ex
ON UserEx.ExpertiseId = Ex.ExpertiseId
Читаемость запроса - это БОЛЬШАЯ помощь для вас и / или любого, кто помогает вам или следит за вами. Отсутствие предложений «on» рядом с соответствующими объединениями может привести к путанице.
Кроме того, это ваша ПЕРВИЧНАЯ таблица, где остальные - справочные таблицы поиска.
ДОПОЛНЕНИЕ ЗА КОММЕНТАРИЙ
Хорошо, я обновил запрос, который, по-видимому, не имеет контекста для данных примера и того, что вы хотите в своем посте. Тем не менее, я бы начал со списка только отелей и подсчета (*) вещей на гостиницу, чтобы вы могли дать НЕКОТОРЫЕ показания того, сколько вещей у вас есть в деталях. Что-то вроде
select
H.HotelID,
H.HotelName,
coalesce( MedSum.recs, 0 ) as MediaItems,
coalesce( LocSum.recs, 0 ) as NumberOfLocations,
coalesce( ComSum.recs, 0 ) as NumberOfLocations
from
Hotel H
LEFT JOIN
( select M.HotelID,
count(*) recs
from Media M
group by M.HotelID ) MedSum
on H.HotelID = MedSum.HotelID
LEFT JOIN
( select L.HotelID,
count(*) recs
from Location L
group by L.HotelID ) LocSum
on H.HotelID = LocSum.HotelID
LEFT JOIN
( select C.HotelID,
count(*) recs
from Comment C
group by C.HotelID ) ComSum
on H.HotelID = ComSum.HotelID
order by
H.HotelName
--- apply any limit per pagination
Теперь это вернет каждую гостиницу на верхнем уровне, и общее количество вещей в отеле на отдельные счета, которые могут существовать или не существовать, следовательно, каждая дополнительная проверка - это ВЕРНУТЬСЯ. Выставляю страницу из 20 разных отелей. Теперь, как только один человек выберет один отель, вы сможете просмотреть информацию о местах, средствах массовой информации и комментарии по этому отелю.
Теперь, хотя это МОЖЕТ работать, выполнение этих подсчетов в запросе каждый раз может занять очень много времени. Возможно, вы захотите добавить встречные столбцы в вашу основную таблицу отелей, представляющую такие подсчеты, как выполняемые здесь. Затем, с помощью какого-то ночного процесса, вы можете повторно обновить счетчики ОДНАЖДЫ, чтобы заполнить их на протяжении всей истории, а затем обновить счетчики только для тех отелей, которые имеют новую активность с тех пор, как они были введены ранее. Не то чтобы у вас было 1 000 000 постов с новыми изображениями, новыми местоположениями, новыми комментариями в день, но из 22 000 - это единственные записи в отелях, для которых вы будете обновлять счет. Каждый инкрементный цикл будет коротким, основываясь только на добавленных новых записях. Для веб-сайтов наличие предварительных суммированных сумм, сумм и т. Д. Позволяет сэкономить много времени.