Программирование баз данных MS SQL Server (1084479), страница 34
Текст из файла (страница 34)
ясог 1с( определенной строки имеется значение, отличное от ((ОЕЬ, то согласно операции О(( конструкции 101(( при наличии в таблице ((1ясоппгя соответствукнцей строки поле с(1ясоппся.ягог 1(( также должно иметь значение, равное значению поля апогея. япог 1с( (поскольку эта операция имеет вид О(( с(. ягог 1с( = я.
ягог 1с(). О( Если в поле апогея. ягог гб определенной строки имеется значение, отличное от ((ОЬЬ, то согласно операции О(( конструкции ООХВ при отсутствии в таблице ((1ясоппся соответствующей строки значение поля ((1ясоппся.ягог 1(( должно быть возвращено как ((ОЕЕ. Е( Если оказалось, что поле апогея. ягог 1(( имеет Х1(ЕЕзначение, а поле сбясоппгя.ягог 1с( также имеет Х1(ЕЕ-значение, то соединение не происходит и вместо значения с(1ясоппгя.
ясог 1с( возвращается Хг(Е(:значение, поскольку соответствие между строками отсутствует. Итак, при наличии в сравниваемых строках обеих таблиц Х(Лз=значений соединение этих строк не выполняется. Это связано с тем, что, как уже было сказано в отношении сравнения ЬП(йу=значений, одно ХШ 1:значение не равно другому. Об этом всегда следует помнить, формулируя текст операторов Ь9Е. Чаще всего вопрос о том, почему данный код не работает, относится к той ситуации, когда предпринимается попытка применить операцию сравнения на равенство к ХВАЛЯ;значениям, и в данном случае ответ найти несложно — попытка сравнить на равенство ВПЛ.Е-значения оканчивается неудачей просто потому, что два 1~ПЛЛ:значения не равны друг другу.
Чтобы проверить на практике это утверждение, достаточно вызвать на выполнение следующий простой код: 1Р (МПЬЬ=НПЬЬ( Ркгпт '1Г Пояя' ЕЬЯЕ РВ1МТ '11 Воеяп''С' 140 Глава 4 После вызова на выполнение этого кода СУБД 5ЯЬ Яегвег сообщает, что результаты операции сравнения одного Х()ЬЬ-значения с другим являются отрицательными, так как на устройстве вывода появляется строка "1С Роз зп ' г" (Не равны). Но фактически получение такикфезуль аиюв было ифедусмотфено окончательно лишь ввеф.
сии 5~Ь 5ееиее 7.О. Следует учитывать, что если ифогфамма 5ЯЬ 5егоег б.5 зксплуатифуетгя в фежиме совместпимости (в наши дни такая ситуация должна быть доппаточно федкой, поскольку фежим совместимости относится к давно ифошедшим вфемеком, но из всякого пфавила бывают исключения) или если иафометфу ЛА)51 А)ОЕЕЗ пфисвоено значение ОЕГ (с памошью опций сгфвефа или с ифимеыением опеф оюфа ЕЕТ), то будет получен дфу вой ответ (сгфвгф будет вьфаботывать положительный фезультот пфи сфавнении двук ЖПл:значений на фавенство). Тем не менее теиефь такой фежизп в котофом сфавнвпие МЛЛ:значений на фавенство пфиводит к иолучению положительного фезультата, считаетсп нестондафтным. Этот фежим фассматфи воется как нафушение стандафта АН51 и больше не является совместимым с конфигуфацией СУБД 5ЯЕ.
5егоее, пфедусмотфен ной по умолчанию. (О том, чию МЛ.1:значения не фавны друг дфугу сказано даже в оперативной документации Вполз Ои1)пе.) Воспользуемся рассматриваемым способом, позволяющим выявлять строки, не имеющие несоответствия, для поиска некоторых строк, не вошедших в состав результатов одного из описанных выше операторов с конструкцией 1ИИЕЕ д01И. Напомним, что для выборки данных из базы данных ИогСАнйпс( применялись в том числе следующие два запроса: ЕЕ'ЕСТ О1ЕТХИСТ с.Созьопег1О, о.Сосрзпунаие ЕАОН Сзвсоизгв с 1ИИЕК ЗО1И Огоегв о ОИ с.сэвсопег1О = о.Созсопег1Р и ЯЕЬЕСТ СООИТ(*) АЯ "Ио.
ОГ аесогав" ЕКОН Сизсопзгв Первый из этих запросов относится к тем примерам, с помощью которых в данной главе рассматривались свойства внутреннего соединения 1ИИЕЕ 101И. А второй запрос позволил выяснить, что в результаты первого запроса не попали (по определению) некоторые строки. Теперь с использованием внешнего соединения определим, какие строки были исключены. Итак, запрос с конструкцией ЕЕЕЕСТ СООИТ (*) позволил определить, что в результаты первого запроса не вошли некоторые строки из таблицы Сцзсоп)егз. (В эти результаты могли также не войти некоторые строки из таблицы Огбегв, но в данный момент нас это не интересует.) На основании этого можно сделать вывод, что в таблице Спвготегз имеются строки, не находящие соответствия среди строк таблицы Огбегв.
При описании этой темы было принято предположение, что запрос составлен в ответ на требование пользователя получить информацию обо всех заказчиках, разместивших в компании свои заказы, но очень часто приходится искать ответ на прямо противоположный вопрос: "Какие заказчики не разместили в компании свои заказы." Этот вопрос по сути равнозначен такому вопросу: "Какие строки в таблице Спяго)аегз не имеют соответствующих строк в таблице Огбегя)" Решением этой задачи становится запрос с такой же структурой, что и в запросе для поиска магазинов, не предоставляющих скидки: Соединения 141 ОБЕ НогяьяТпс БЕЬЕСТ с.Спяяоэег1О, Соэрапуиэпе РНОН Спя оэегя с ЬЕРТ ОСТЕН 501Н Огпегя о ОН с.спяпопег1О = о.спяяотег1О ХНЕНЕ о.сияпоэег10 15 НОЬЬ Итак, с помощью одного из предыдущих запросов мы сумели без особых сложностей узнать количество заказчиков, которые не разместили свои заказы, а последний запрос дал возможность определить названия компаний этих заказчиков (и вскоре, возможно, с ними свяжется коммерческий отдел...): Спяпоаег1О Соарапуиаэе Рагяя яресяа1ясея Р155А Раьгяса 1пяег.
Ба1снлсная Б.А. РАН15 Р15БА ~2 соя(я) атуесяен1 Следует:Отментзить,:.'чу 'результат, 'прияысаичиня Ксннструкцнй:-ЬРЕт';:Озожи'-нптойт'.ЛИИ-остж-' Етая' 'ОдпвияаКОЕЫ(ыу Прм уоЛОВИИ' Чтс:дяя:раЗМЕц(ЕНИЕ':ОтйаЛЬИЫХГ табЛИц'-ИЛИТруцП,табаюц СООТВЕятотауНяйцая ЧаЕВ КОНСтруацИИ йахеде(цааСЛ:СЛЕВа';Йт)И:6)(рава'От".КОНбуряуж(ИИ'ООТГ, ВЫбюраатСя', ПраамдЬИО .'НЕО)рИМСЕр;:,'ПрадЬтдущкй-'ЗаПрОС-МОжис 6ЫЛО, 6Ы',СОдяИНаКОаЫМ' усйехом;,составить':,с."-оп(уяьэовайием коиструкцйи-й)Тите',10тм;-, 'йри;ус)к)ая(и, чуб 'имена таблиц сппяясоапеяся:-'исогсеяэпозотнпояшенигкьк(клочеабмуя олопеузоя"'иломатняплиеь бы ме- СятаМИ.,'=йаПрИМЕр„''аЛцду(рщпИй;ОяоарэатЩулрЬИЕОдвт",КО()яуэяаСИИЮ-'трЧНОстаэхнпХ ИЕ('рвэуЛЬтатса, Беьестяс,ецясэсиетто -сея1рапуиаие' ХТОНТ"'ОЬТЕА,',:а~та-'СряеоаЕГя'С Он:-с;;сйв:.'овегТО)':-;,',,ояооэс) р)яеутсся 'ЙКЕЕЕ';-о'.
Сая СОН 'С10:,."Б,"ИОЬЬ Применение более сложных внешних соединений Переходим к изучению второй из тем, указанных в начале данной главы, а также к рассмотрению практических примеров. В данном разделе речь пойдет исключительно о том, как конструкции ООТЕК 501М используются с другими разновидностями конструкции Ю01М (независимо от того, каковыми являются эти разновидности). Понимание того, какие таблицы должны рассматриваться как находящиеся слева ияи справа от ключевого слова 501н, становится еще более важным, когда внешнее После того как речь пойдет о еще более сложных запросах, будет описан немного более удобный и широко применяемый способ поиска таких строк, имеющихся в одной таблице, для которых отсутствуют соответствующие строки в другой таблице. Тем не менее следует заранее отметить, что обычно соединения позволяют выполнять указанную задачу с наибольшей производительностью.
Из этого правила есть исключения, о которых будет сказано при описании соответствующей темы, но, вообще говоря, если имеется несколько способов сравнения таблиц по указанному принципу, то соединения являются наилучшими из них. 142 Глава 4 соединение применяется в сочетании с другими соединениями. Необходимо учитывать, что с точки зрения включения или исключения из результатов запроса конкретных строк все таблицы, находящиеся "слева" (или перед) от рассматриваемого ключевого слова ЮОХИ, о котором идет речь, должны рассматриваться так, как если бы это была одна таблица.
То же утверждение является справедливым по отношению к таблицам, находящимся "справа" (или после) ключевого слова ЯОПй. Если это не учитывается, то возникает такая распространенная ошибка, как применение в начальной части запроса левого внешнего соединения, а затем выполнения внутреннего соединения в последней части запроса. Ко времени выполнения внутреннего соединения осуществление внешнего соединения приведет к тому, что в результат будут включены все строки одной из таблиц, притом что дальнейшее использование внутреннего соединения все равно может потребовать исключения части результатов! По мнению автора, для большинства разработчиков подобный ход выполнения операций соединения на первых порах кажется весьма труднодоступным для понимания (это касалось и меня самого), поэтому в настоящем разделе суть сказанного будет проиллюстрирована на примерах.
Тем не менее ни в одной из баз данных, поставляемых вместе с СУБД Я~Е Бегнег, нет таких таблиц, которые позволили бы составить удачный сценарий для демонстрации подобных сложных операторов соединения, поэтому вначале необходимо создать отдельную базу данных и ввести в нее данные, которые будут применяться в дальнейших примерах. Образцовая база данных, называемая СЛарСег40В, с помощью которой можно самому проследить за выполнением следующих примеров, может быть создана путем вызова на выполнение сценария СЬарсег40В.
Яц1 из загруженного с ЪЧеЬ-узла автора исходного кода. Выполнение дальнейших действий будет осуществляться по такому принципу: мы будем шаг за шагом усложнять запрос и следить за тем, что происходит. В конечном итоге должен быть создан запрос, который возвращает имя и адрес поставщика. Количество данных в образцовой базе данных невелико, поэтому начнем с того, что определим все варианты выбора центральной позиции в запросе — имени поставщика.