KnigaRead.com/

Мартин Грубер - Понимание SQL

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мартин Грубер, "Понимание SQL" бесплатно, без регистрации.
Перейти на страницу:

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

Вы можете сделать это с помощью определения временных имен называемых переменными диапазона, переменными корреляции или просто - псевдонимами. Вы определяете их в предложении FROM запроса. Это очень просто: вы набираете имя таблицы, оставляете пробел, и затем набираете псевдоним для нее. Имеется пример который находит все пары заказчиков имеющих один и тот же самый рейтинг (вывод показывается в Таблице 9.1):


SQL Execution Log

SELECT first.cname, second.cname, first.rating

FROM Customers first, Customers second

WHERE first.rating=second.rating;


Giovanni

Giovanni

200

Giovanni

Liu

200

Liu

Giovanni

200

Liu

Liu

200

Grass

Grass

300

Grass

Cisneros

300

Clemens

Hoffman

100

Clemens

Clemens

100

Clemens

Pereira

100

Cisneros

Grass

300

Cisneros

Cisneros

300

Pereira

Hoffman

100

Pereira

Clemens

100

Pereira

Pereira

100


Таблица 9.1: Объединение таблицы с собой


(обратите внимание что в Таблице 9.1, как и в некоторых дальнейших примерах, полный запрос не может уместиться в окне вывода, и следовательно будет усекаться.)

В вышеупомянутой команде, SQL ведет себя так, как если бы он соединял две таблицы называемые 'первая' и 'вторая'. Обе они - фактически, таблицы Заказчика, но псевдонимы разрешают им быть обработаными независимо. Псевдонимы первый и второй были установлены в предложении FROM запроса, сразу после имени копии таблицы. Обратите внимание что псевдонимы могут использоваться в предложении SELECT, даже если они не определены в предложении FROM.

Это - очень хорошо. SQL будет сначала допускать любые такие псевдонимы на веру, но будет отклонять команду если они не определены далее в предложении FROM запроса.

Псевдоним существует - только пока команда выполняется ! Когда запрос заканчивается, псевдонимы используемые в нем больше не имеют никакого значения.

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

УСТРАНЕНИЕ ИЗБЫТОЧНОСТИ

Обратите внимание что наш вывод имеет два значение для каждой комбинации, причем второй раз в обратном порядке. Это потому, что каждое значение показано первый раз в каждом псевдониме, и второй раз( симметрично) в предикате. Следовательно, значение A в псевдониме сначала выбирается в комбинации со значением B во втором псевдониме, а затем значение A во втором псевдониме выбирается в комбинации со значением B в первом псевдониме. В нашем примере, Hoffman выбрался вместе с Clemens, а затем Clemens выбрался вместе с Hoffman. Тот же самый случай с Cisneros и Grass, Liu и Giovanni, и так далее. Кроме того каждая строка была сравнена сама с собой, чтобы вывести строки такие как - Liu и Liu. Простой способ избежать этого состoит в том, чтобы налагать порядок на два значения, так чтобы один мог быть меньше чем другой или предшествовал ему в алфавитном порядке. Это делает предикат ассиметричным, поэтому те же самые значения в обратном порядке не будут выбраны снова, например:


SELECT tirst.cname, second.cname, first.rating

FROM Customers first, Customers second

WHERE first.rating=second.rating

AND first.cname < second.cname;


Вывод этого запроса показывается в Таблице 9.2.


Hoffman предшествует Periera в алфавитном порядке, поэтому комбинация удовлетворяет обеим условиям предиката и появляется в выводе. Когда та же самая комбинация появляется в обратном порядке - когда Periera в псевдониме первой таблицы сравнтвается с Hoffman во второй таблице псевдонима - второе условие не встречается. Аналогично Hoffman не выбирается при наличии того же рейтинга что и он сам потому что его имя не предшествует ему самому в алфавитном порядке. Если бы вы захотели


SQL Execution Log

SELECT first.cname, second.cname, first.rating FROM Customers first, Customers second

WHERE first.rating=second.rating

AND first.cname < second.cname

cname

cname

rating

Hoffman

Pereira

100

Giovanni

Liu

200

Clemens

Hoffman

100

Pereira

Pereira

100

Gisneros

Grass

300


Таблица 9.2: Устранение избыточности вывода в обьединении с собой.


включить сравнение строк с ними же в запросах подобно этому, вы

могли бы просто использовать <=вместо <.

ПРОВЕРКА ОШИБОК

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


SELECT first.onum, tirst.cnum, first.snum,

second.onum, second.cnum,second.snum

FROM Orders first, Orders second

WHERE first.cnum=second.cnum

AND first.snum < > second.snum;


Хотя это выглядит сложно, логика этой команды достаточно проста. Она будет брать первую строку таблицы Порядков, запоминать ее под первым псевдонимом, и проверять ее в комбинации с каждой строкой таблицы Порядков под вторым псевдонимом, одну за другой. Если комбинация строк удовлетворяет предикату, она выбирается для вывода. В этом случае предикат будет рассматривать эту строку, найдет строку где поле cnum=2008 а поле snum=1007, и затем рассмотрит каждую следующую строку с тем же самым значением поля cnum. Если он находит что какая -то из их имеет значение отличное от значения поля snum, предикат будет верен, и выведет выбранные поля из текущей комбинации строк. Если же значение snum с данным значением cnum в наш таблице совпадает, эта команда не произведет никакого вывода.

БОЛЬШЕ ПСЕВДОНИМОВ

Хотя обьединение таблицы с собой - это первая ситуация когда понятно что псевдонимы необходимы, вы не ограничены в их использовании что бы только отличать копию одлной таблицы от ее оригинала. Вы можете использовать псевдонимы в любое время когда вы хотите создать альтернативные имена для ваших таблиц в команде. Например, если ваши таблицы имеют очень длинные и сложные имена, вы могли бы определить простые односимвольные псевдонимы, типа a и b, и использовать их вместо имен таблицы в предложении SELECT и предикате. Они будут также использоваться с соотнесенными подзапросами(обсуждаемыми в Главе 11).

ЕЩЕ БОЛЬШЕ КОМПЛЕКСНЫХ ОБЪЕДИНЕНИЙ

Вы можете использовать любое число псевдонимов для одной таблицы в запросе, хотя использование более двух в данном предложении SELECT * будет излишеством. Предположим что вы еще не назначили ваших заказчиков к вашему продавцу. Компании должна назначить каждому продавцу первоначально трех заказчиков, по одному для каждого рейтингового значения. Вы лично можете решить какого заказчика какому продавцу назначить, но следующий запрос вы используете чтобы увидеть все возможные комбинации заказчиков которых вы можете назначать. (Вывод показывается в Таблице 9.3 ):


SQL Execution Log

SELECT a.cnum, b.cnum, c.cnum

FROM Customers a, Customers b, Customers c

WHERE a.rating=100

AND b.rating=200

AND c.rating=300;

AND c.rating=300;


cnum

cnum

cnum

2001

2002

2004

2001

2002

2008

2001

2003

2004

2001

2003

2008

2006

2002

2004

2006

2002

2008

2006

2003

2004

2006

2003

2008

2007

2002

2004

2007

2002

2008

2007

2003

2004

2007

2003

2008


Таблица 9.3 Комбинация пользователей с различными значениями рейтинга

Как вы можете видеть, этот запрос находит все комбинации заказчиков с тремя значениями оценки, поэтому первый столбец состоит из заказчиков с оценкой 100, второй с 200, и последний с оценкой 300. Они повторяются во всех возможных комбинациях. Это - сортировка группировки которая не может быть выполнена с GROUP BY или ORDER BY, поскольку они сравнивают значения только в одном столбце вывода.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*