Конструктор запросов в SSMS и порядок последовательности соединения? - PullRequest
4 голосов
/ 07 сентября 2011

В SSMS есть конструктор запросов, которого я обычно избегаю, потому что, честно говоря, я не могу по-настоящему с ним работать.

К сожалению, мои коллеги делают. Поскольку у меня остается 30 минут, я, наконец, хочу узнать, являюсь ли я проблемой или SSMS.

Например: Давайте предположим, что у нас есть таблица зданий, таблица этажей, таблица комнат и таблица сопоставления use_types (room-Использование_types).

Когда я создаю запрос вручную, я делаю это:

select all buildings, 
left join all floors in those buildings
left join all rooms in those floors
left join the room-usage_types mapping table.

Теперь, когда я пытаюсь сделать то же самое в конструкторе запросов, он каким-то образом начинается со таблицы сопоставления, затем слева соединяется с комнатами, слева соединяется с этажами, а затем слева соединяется со зданиями.

Что в корне неверно, потому что если в таблице сопоставления нет записи для комнаты, она не вернет все комнаты (предполагается, что каждая комната обязательно находится на этаже, а каждый этаж обязательно в здании, но не в каждой комнате обязательно есть тип использования, связанный с самим собой [на определенный период времени]) ...

Теперь, если я начну изменять объединения, я получу этот запрос

SELECT  
FROM usage_type mapping 
RIGHT OUTER JOIN Floors 
LEFT OUTER JOIN Rooms 
RIGHT OUTER JOIN Floors

Теперь этот запрос кажется эквивалентным, но это пример, и обычно мне нужно объединить еще много таблиц. Поэтому мне не особенно нравится сочетание правого и левого объединений, потому что в конце это трудно понять (особенно, когда несколько операторов ON не следуют в месте, где выполняется объединение), что делает поиск ошибок почти невозможным (и я не очень доверяю способности дизайнера запросов выяснить, чего я хочу).

До сих пор я не нашел способа «спроектировать» запрос так, как я хочу. Похоже, что единственный способ - создать исходный запрос, затем получить текст SQL, затем настроить объединения, а затем снова открыть его с помощью конструктора запросов SQL.

Само собой разумеется, что в конечном итоге это занимает больше времени, чем в первую очередь ручное выполнение, и когда сценарий SQL был изменен конструктором запросов, вы больше не сможете его прочитать, не переформатировав его сначала вручную ... .

Мне кажется, что мой вариант совершенно невозможно реализовать с помощью конструктора запросов ... Что я нахожу особенным, так это то, что в конструкторе запросов, в контекстном меню символа соединения, иногда таблица слева вверху, а иногда таблица справа.

И затем, когда мне нужно выбрать нижний вместо верхнего, он выполняет правильное соединение. Я могу выбрать верхний, затем он выполняет левое соединение, но в неправильной последовательности ... это именно то, чего я не хочу ...

Итак, я хотел спросить: Есть ли какой-то «секретный» способ указать, с какой таблицы должен начинаться запрос, желательно без каких-либо правых соединений?

1 Ответ

1 голос
/ 11 сентября 2011

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

CREATE TABLE buildings(
building_id int primary key)

CREATE TABLE floors(
floor_id int primary key,
building_id int references buildings)

CREATE TABLE rooms(
room_id int primary key,
floor_id int references floors)

CREATE TABLE room_usage_types(
room_id int references rooms,
usage_type_id int,
PRIMARY KEY  (room_id,usage_type_id))

Открыв окно «Дизайн запроса в редакторе» и добавив 4 таблицы, удерживая клавишу CTRL, нажимая, я обнаружил, что в каком порядке вы выбираете их, имеет значение.

Если вы выберете в заказе room_usage_types, rooms, buildings, Daily, тогда вы начнете с не очень полезного

SELECT     
FROM         rooms INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id CROSS JOIN
                      buildings CROSS JOIN
                      Daily

Но если вы выберете в порядке buildings, floors, rooms, room_usage_types, вы получите гораздо более перспективный

SELECT     
FROM         buildings INNER JOIN
                      floors ON buildings.building_id = floors.building_id INNER JOIN
                      rooms ON floors.floor_id = rooms.floor_id INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id

Начиная с этой начальной точки, не нажимайте кнопку «Выбрать все строки из зданий», поскольку она преобразует запрос в приведенный ниже.

SELECT     
FROM         rooms INNER JOIN
                      floors ON rooms.floor_id = floors.floor_id INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id RIGHT OUTER JOIN
                      buildings ON floors.building_id = buildings.building_id

Вместо этого работайте справа налево, начиная с ромба между rooms, room_usage_types и выбирая «Выбрать все ряды из комнат» и так далее. Это, кажется, дает желаемый результат.

SELECT     
FROM         buildings LEFT OUTER JOIN
                      floors ON buildings.building_id = floors.building_id LEFT OUTER JOIN
                      rooms ON floors.floor_id = rooms.floor_id LEFT OUTER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...