УСТРАНЕНИЕ ИЗБЫТОЧНОСТИ
Обратите внимание что наш вывод имеет два значение для каждой комбинации, причем второй раз в обратном порядке.
Это потому, что каждое значение показано первый раз в каждом псевдониме, и второй раз( симметрично) в предикате.
Следовательно, значение 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 в алфавитном порядке, поэтому
комбинация удовлетворяет обеим условиям предиката и появляется в выводе. Когда та же самая комбинация появляется
в обратном порядке - когда Perie- ra в псевдониме первой таблицы сравнтвается с Hoffman во второй таблице
псевдонима - второе условие не встречается. Аналогично Hoffman не выбирается при наличии того же рейтинга
что и он сам потому что его имя не предшествует ему самому в алфавитном порядке. Если бы вы захотели включить
сравнение строк с ними же в запросах подобно этому, вы могли бы просто использовать < = вместо <.
cname |
cname |
rating |
Hoffman |
Pereira |
100 |
Giovanni |
Liu |
200 |
Clemens |
Hoffman |
100 |
Pereira |
Pereira |
100 |
Gisneros |
Grass |
300 |
Рисунок 9.2: Устранение избыточности вывода в обьединении с собой.