Внутрішні об’єднання

Внутрішні обєднання є найпоширенішими в роботах Едгара Кодда вони називалися природними Внутрішні обєднання повертають тільки ті рядки, які відповідають один одному у двох наборах даних Внутрішнє обєднання отримало свою назву з тієї причини, що воно витягує дані з внутрішньої частини перетину двох множин даних (рис 93)

Внутрішні обєднання легко створити в утиліті Management Studio за допомогою графічного інструменту Query Designer (рис 94) Після того як дві таблиці поміщені на панель діаграми за допомогою функції Add Table або методу перетягування зі списку таблиць, обєднання створюється автоматично, якщо ці таблиці містять загальні поля Якщо ви не збираєтеся використовувати це обєднання, то його доведеться видалити вручну

У конструкторі запитів для кожного типу обєднання використовується свій символ (див табл 91) Символ, використовуваний для внутрішнього обєднання, має вигляд ромбика

Puc 94 Створення внутрішнього обєднання в конструкторі запитів Management Studio

Створення внутрішнього обєднання в коді SQL

У коді SQL обєднання визначаються в реченні FROM інструкції SELECT Ключове слово JOIN ідентифікує другу таблицю, a ON – поля, на яких будується пошук відповідності між таблицями Внутрішнє обєднання використовується в SQL за замовчуванням, тому ключове слово INNER є необовязковим

SELECT *

FROM Tablel [INNER] JOIN Table2

ON Tablelcolumn = Table2column

Приклади баз даних і коду, використовувані в цій главі, можна завантажити Із сайту wwwSQLServerBiblecom

Так як обєднання зводять дані з двох наборів, то бажання SQL знати, як шукати відповідності, має вагомі причини SQL Server повязує рядки на основі загальних значень в полях обєднання обох таблиць Зазвичай первинний ключ однієї таблиці порівнюється із зовнішнім ключем другий Якщо рядок з однієї таблиці знаходить відповідність з деякою рядком другої таблиці, то обидві ці рядки обєднуються в одну, яка містить дані з обох таблиць

У наступному прикладі обєднуються таблиці Tour (зовнішній ключ) і Base Camp (первинний ключ) бази даних Cape Hatteras Adventures:

USE СНА2

SELECT TourName, TourBaseCampID,

BaseCampBaseCampID, BaseCampName FROM dboTour JOIN dboBaseCamp

ON TourBaseCampID = BaseCampBaseCampID

Запит починається з таблиці Tour Для кожного рядка цієї таблиці SQL Server буде намагатися знайти відповідні рядки таблиці BaseCamp, порівнюючи значення полів BasecampID обох таблиць Відповідні рядки таблиць Tour і BaseCamp сформують наступний результат:

Tour                                Tour                            Basecamp Basecamp

TourName                        BaseCampID               BaseCampID BaseCampName

Appalachian Trail            1                                  1                         Ashville NC

Outer Banks Lighthouses                                    2                         2  Cape Hatteras

Bahamas Dive                 3                                  3                         Freeport

Amazon Trek                  4                                  4                         Ft Lauderdale

Gauley River Rafting      5                                  5                         West Virginia

Кількість повертаються рядків

У наведеному прикладі всі рядки таблиць Tour і BaseCamp мали відповідності, при цьому з обєднання не було виключено жодного рядка Однак у реальному житті такі випадки – рідкість Залежно від кількості відповідних рядків в кожному з джерел даних і типу обєднання кількість рядків у результуючому наборі даних може як зменшитися, так і збільшитися

Щоб зрозуміти, як обєднання впливає на кількість повертаються рядків, розглянемо таблиці Contact і [Order] бази даних OBXKites Початкове кількість клієнтів складає 21, однак після зіставлення з замовленнями їх число скоротилося до 10 В наступному фрагменті коду ми порівняємо пліч-о-пліч два запити і їх результати:

USE OBXKites

SELECT ContactCode, LastName SELECT ContactCode, OrderNumber FROM dboContact      FROM dboContact

ORDER BY ContactCode                      JOIN dbo[Order]

ON [Order]ContactID

= ContactContactID ORDER BY ContactCode ContactCode LastName ContactCode OrderNumber

101&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Smith 101                                   1

101 2

101&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp 5

102&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Adams 102                                 6

102&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp 3

103&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Reagan 103                                4

103&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp 7

104&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Franklin 104                               8

105&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Dowdry 105                               9

106&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Grant 106                                   10

107&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Smith

108&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Hanks

109&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp James

110&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Kennedy

111&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Williams

112&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Quincy

113&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Laudry

114&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Nelson

115&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Miller

116&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Jamison

117&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Andrews

118&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Boston

119&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Harrison

120&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Earl

121&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Zing

Тільки контакти 101-106 мають відповідні їм замовлення, інші були виключені з обєднання

Обєднання можуть також приводити до збільшення кількості рядків Якщо рядок з одного боку обєднання має безліч відповідностей з іншого, то результат буде містити по одному рядку для кожного з цих відповідностей У наведеному вище прикладі деякі клієнти (Smith, Adams і Reagan) повторюються в результуючому наборі даних кілька разів, оскільки мають кілька замовлень

Залежно від допустимості порожніх значень в ключах на обох кінцях, обєднання мають тенденцію втрачати рядки, тому що одна або інша таблиця відтворює некоректні дані Коли дані витягуються з безлічі таблиць, для запиту рекомендується ретельно вибирати тип обєднання (внутрішнє, ліве зовнішнє або праве зовнішнє), щоб у результуючому наборі даних містилися всі і кожна потрібні рядки

Обєднання ANSI SQL-89

Обєднання – це не що інше, як відбір даних з двох таблиць, для яких виконується умова рівності між значеннями загальних стовпців Умови обєднання в запропонованого-

жении ON аналогічні умовам в реченні WHERE Насправді, поки ANSI SQL-92 не стандартизовані синтаксис вираження JOIN ON, стандарт ANSI SQL-89, також званий обєднанням застарілого стилю, виконував ту ж задачу за допомогою перерахування таблиць у реченні FROM і визначення умов обєднання в пропозиції WHERE SQL Server підтримує обидва синтаксису: ANSI SQL-92, і ANSI SQL-89

Наведене в попередньому прикладі обєднання таблиць Contact і [Order] в старому стандарті синтаксису мало б такий вигляд:

SELECT ContactContactCode, [Order]OrderNumber FROM dboContact, dbo[Order]

WHERE [Order]ContactID = ContactContactID ORDER BY ContactCode

Особисто я вважаю за краще використовувати для обєднання стандарт ANSI SQL-92 JOIN ON, оскільки він дозволяє повністю визначити обєднання в пропозиції FROM Стандарт ANSI-89 розбиває визначення обєднання на дві пропозиції, що, на мою думку, більшою мірою схильне ймовірності помилок У той же час жоден з цих стилів не має переваг в продуктивності, оскільки SQL Server створює ідентичний план виконання запиту для кожного з них

Обєднання безлічі таблиць

У деяких продемонстрованих прикладах інструкція SELECT обмежувалося одним або двома джерелами даних У загальному випадку інструкція SELECT може звертатися до 255 джерел даних Уявіть собі, скільки обєднань може містити така інструкція Так як SQL є декларативною мовою, порядок джерел даних в інструкції SELECT не має значення Обєднання можуть бути сформовані в ній в безліч ланцюжків, навіть кільцевих (наприклад, А обєднується з В В – з С С – з А) Саме тут на перше місце виходить послідовний стиль розробки

Коли обєднання між безліччю таблиць комбінуються з обмеженнями пропозиції WHERE (тобто ці обмеження впливають на всі обєднуються таблиці), часом відбуваються нетривіальні речі Обмеження, що накладається на одну таблицю, має на увазі, що тільки рядки, що задовольняють йому, беруть участь в обєднанні

Наступний запит (показаний на рис 95 і описаний в коді) відповідає на питання: Хто купував повітряних зміїв” У формуванні відповіді на це питання беруть участь наступні таблиці

1 Таблиця Contact відповідає на питання: Хто”

2 Таблиця [Order] відбирає замовлення

3 Таблиця OrderDetails відбирає товари

4 Таблиця Product вибирає категорії товарів

5 Таблиця Product Category шукає категорію kites.

Наступна інструкція SELECT починається з фрагмента питання хто і визначає таблиці, що беруть участь в обєднанні, і накладаються на них умови Запит, показаний графічно на рис 95 у вікні конструктора запитів утиліти Management Studio, мовою SQL має наступний вигляд (зверніть увагу на те, що пропозиція WHERE обмежує рядка таблиці Product Category, що беруть участь в обєднанні):

USE OBXKites

SELECT LastName, FirstName, ProductName

FROM dboContact

JOIN dbo[Order]

ON ContactContactID = [Order]ContactID JOIN dboOrderDetail

ON [Order]OrderlD = OrderDetailOrderlD JOIN dboProduct

ON OrderDetailProductID = ProductProductID JOIN dboProductCategory

ON ProductProductCategorylD

= ProductCategoryProductCategorylD WHERE ProductCategoryName = Kite

ORDER BY LastName, FirstName

Puc 95 Пошук відповіді на питання Хто купував повітряних зміїв” В конструкторі запитів утиліти Management Studio

Результат виконання запиту буде наступним:

LastName         FirstName                                  ProductName

Adams              Terri                                           Dragon Flight

Dowdry            Quin                                           Dragon Flight

Smith                Ulisius                                        Rocket Kite

Порівняно із запитом, згенерованим конструктором запитів, запит, наведений в попередньому коді, легше зрозуміти Хоча конструктор значною мірою полегшує створення запитів, згенерований їм код важкий для сприйняття Конструктор запитів іноді віддаляє умови ON від обєднуються таблиць, а створюване їм форматування просто жахливо

Джерело: Нільсен, Пол Microsoft SQL Server 2005 Біблія користувача : Пер з англ – М: ООО ІД Вільямс , 2008 – 1232 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*