Общие сведения об основных понятиях и синтаксисе соединений
Наиболее фундаментальным и распространенным методом объединения данных из нескольких таблиц является использование операции JOIN. Одни пользователи считают, что JOIN является отдельным предложением в инструкции SELECT, а другие рассматривают его как часть предложения FROM. В этом модуле мы будем использовать JOIN как часть предложения FROM. В этом модуле мы узнаем, как предложение FROM в инструкции SELECT в T-SQL создает промежуточные виртуальные таблицы, которые будут использоваться на последующих этапах запроса.
Предложение FROM и виртуальные таблицы
Если вы изучали логический порядок операций, выполняемых SQL Server при обработке запроса, вам известно, что первым обрабатывается предложение FROM оператора SELECT. Это предложение определяет, какая таблица или таблицы будут источником строк для запроса. Предложение FROM может ссылаться на одну таблицу или объединить несколько таблиц в качестве источника данных для запроса. Предложение FROM можно представить в виде источника для создания и заполнения виртуальной таблицы. Эта виртуальная таблица будет содержать выходные данные предложения FROM и использоваться предложениями инструкции SELECT, которые применяются позже, например предложением WHERE. По мере добавления к предложению FROM дополнительных функциональных возможностей, таких как операторы соединения, станет ясно, что элементы предложения FROM предназначены для добавления строк в виртуальную таблицу или удаления их из нее.
Виртуальная таблица, созданная предложением FROM, является только логической сущностью. В SQL Server ни одна физическая таблица, постоянная или временная, не создается для хранения результатов предложения FROM, так как они передаются в предложение WHERE или другие части запроса.
Виртуальная таблица, созданная предложением FROM, содержит данные из всех объединенных таблиц. Это может быть полезно, чтобы думать о результатах как наборы, и концептуально рассматривать результаты соединения как диаграмму Венна.
В ходе своего времени существования язык T-SQL расширялся с учетом изменений стандартов ANSI для языка SQL. Эти изменения более всего заметны в синтаксисе соединений в предложении FROM. В стандарте ANSI SQL-89 соединения задавались путем включения нескольких таблиц в предложение FROM в виде списка, разделенного запятыми. Любая фильтрация для определения строк, которые следует включить, выполнялась в предложении WHERE, как показано ниже:
SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p, SalesLT.ProductModel AS m
WHERE p.ProductModelID = m.ProductModelID;
Этот синтаксис по-прежнему поддерживается в SQL Server, но из-за сложности представления фильтров для сложных соединений использовать его не рекомендуется. Кроме того, если предложение WHERE будет случайно опущено, то соединения в стиле ANSI SQL-89 могут легко стать декартовыми произведениями и будут возвращать чрезмерное количество результирующих строк, приводя к проблемам с производительностью и, возможно, неверным результатам.
При изучении вопроса написания запросов к нескольким таблицам в T-SQL важно понимать концепцию декартовых произведений. В математике декартово произведение является произведением двух наборов. Произведение набора из двух элементов и набора из шести элементов представляет собой набор из 12 элементов или 6 x 2. Каждый элемент в одном наборе объединяется с каждым элементом в другом наборе. В приведенном ниже примере существует набор имен с двумя элементами и набор продуктов с тремя элементами. Декартово произведение объединяет каждое имя с каждым продуктом, и в итоге мы получаем шесть элементов.
В базах данных декартово произведение является результатом объединения каждой строки в одной таблице с каждой строкой в другой таблицы. Произведением таблицы с 10 строками и таблицы со 100 строками будет результирующий набор с 1000 строк. Базовый результат операции JOIN представляет собой декартово произведение, но для большинства запросов T-SQL он является нежелательным. В T-SQL декартово произведение можно получить при объединении двух входных таблиц без учета связей между ними. Не имея сведений о связях, обработчик запросов SQL Server возвратит все возможные сочетания строк. Хотя этот результат может иметь некоторые практические применения, например, для генерации тестовых данных, обычно он не является полезным и может оказывать серьезное влияние на производительность.
С появлением стандарта ANSI SQL-92 была добавлена поддержка ключевых слов JOIN и предложений ON. T-SQL также поддерживает этот синтаксис. Соединения представлены в предложении FROM с помощью соответствующего оператора JOIN. Логическая связь между таблицами, которая становится предикатом фильтра, указывается в предложении ON.
В следующем примере предыдущий запрос заменяется новым синтаксисом:
SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductModel AS m
ON p.ProductModelID = m.ProductModelID;
Примечание.
Синтаксис ANSI SQL-92 усложняет создание случайных декартовых произведений. Если предложение ON отсутствует, после добавления ключевого слова JOIN будет возникать синтаксическая ошибка, пока соединение не будет указано как CROSS JOIN.