Sql влево или вправо присоединиться к нумерации страниц - PullRequest
0 голосов
/ 07 апреля 2019

У меня есть одна основная таблица, и я присоединяюсь к другим таблицам через левое внешнее или правое внешнее соединение. В результате в одной строке главной таблицы в запросе на соединение содержится более 30 строк.И я пробую нумерацию страниц.Но проблема в том, что я не могу знать, сколько строк он вернет для одного результата строки основной таблицы.

Пример:

Результат первой строки основной таблицы в моем запросе 40 строк.Результат второй строки основной таблицы составляет 120 строк.

Задача (вопрос) ОБНОВЛЕНИЕ: Для разбивки на страницы мне нужно указать размер страницы для результата выбора.Но я не могу знать правильный счет для моего выбора результата.Пример Я даю страницу № 1 и размер страницы 50, из-за этого я не могу получить правильный результат. Мне нужно дать правильный размер страницы для моего результата из первой десятки главной таблицы.Может быть, для первой десятки будет результат 200 строк, но мой размер страницы 50, это проблема.

Я использую Sql 2014. Мне это нужно для моего проекта ASP.NET, но это не важно.

Пример ОБНОВЛЕНИЯ:

это похоже напоиск отеля для бронирования.Ваш главный стол - гостиничный стол.И другие вещи - это (опосредованные) изображения, (опосредованные) видео, (размещаемые) места и, возможно, (комментируемые) комментарии, они состоят из нескольких строк и имеют отношение один ко многим для отеля.Для одного отеля результат составит 100, 50 или 10 строк для всей этой информации.И я пытаюсь разбить этот результат на отели.Мне нужно всегда получать 20, 30 или 50 отелей для выступления в моем проекте.

ОБНОВЛЕНИЕ образца запроса:

   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




Hotel Table : 
HotelId   HotelName
1         Barcelona
2         Berlin


Media Table :
MediaID   MediaUrl      HotelId
1         www.xxx.com   1
2         www.xxx.com   1
3         www.xxx.com   1
4         www.xxx.com   1


Location Table :
LocationId   Adress          HotelId 
1            xyz, Berlin     1
2            xyz, Nice       1
3            xyz, Sevilla    1
4            xyz, Barcelona  1


Comment Table :
CommentId   Comment             HotelId
1           you are cool        1
2           you are great       1
3           you are bad         1
4           hmm you are okey    1

Это только образец!В моей базе 9999999 отелей.Представьте себе, что в отеле может быть 100 изображений, а может и ноль.Я не могу этого знать.И мне нужно получить 20 отелей в моем результате (нумерация страниц).Но 20 отелей означают 1000 рядов или 100 рядов.

1 Ответ

2 голосов
/ 08 апреля 2019

Во-первых, ваш запрос плохо написан для потока читаемости / взаимосвязи таблиц. Я обновил и отступ, чтобы попытаться показать, как / где таблицы связаны в иерархической относительности.

Вы также хотите разбить на страницы, давайте вернемся к этому. Намереваетесь ли вы показать каждую запись в качестве возможного элемента, или вы намеревались показать набор данных «родительского» уровня ... Например, у вас есть только один экземпляр на носитель, на пользователя или что-то еще, затем, как только эта запись будет Вы выбрали бы показать детали для этого одного лица? если это так, я бы сделал запрос 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 - это единственные записи в отелях, для которых вы будете обновлять счет. Каждый инкрементный цикл будет коротким, основываясь только на добавленных новых записях. Для веб-сайтов наличие предварительных суммированных сумм, сумм и т. Д. Позволяет сэкономить много времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...