Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по SQL.DOC
Скачиваний:
205
Добавлен:
01.05.2014
Размер:
1.16 Mб
Скачать

7.10.. Объединения таблиц по равенству значений

в столбцах и другие виды объединений

Обьединения, которые используют предикаты, основанные на равенствах, называются объединениями по равенству. Все предыдущие примеры относились именно к этой категории потому, что все условия в предложениях WHERE базировались на математических выражениях, использующих знак равно ( = ). Строки ‘city = ‘London’ и ‘Salespeople.snum = Orders.snum ‘ - примеры таких типов равенств найденных в предикатах.

Объединения по равенству - это вероятно наиболее общий вид объединения, но имеются и другие. Вы можете, фактически, использовать любой из реляционных операторов в обьединении. Здесь показан пример другого вида объединения:

========== SQL Execution Log =====

SELECT sname, cname

FROM Salespeople, Customers

WHERE sname < cname AND rating < 200;

========================

| sname cname |

|-----------------------------------------|

| Peel Pereira |

| Motika Pereira |

| Axelrod Hoffman |

| Axelrod Clemens |

| Axelrod Pereira |

========================

Такая команда не часто бывает полезна. Она воспроизводит все комбинации имени продавца и имени заказчика так, что первый предшествует последнему в алфавитном порядке, а последний имеет оценку меньше чем 200.

7.11.. Объединение более двух таблиц

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

=============== SQL Execution Log =============

| SELECT onum, cname, Orders.cnum, Orders.snum |

| FROM Salespeople, Customers, Orders |

| WHERE Customers.city < > Salespeople.city |

| AND Orders.cnum = Customers.cnum |

| AND Orders.snum = Salespeople.snum; |

|============================================|

| onum cname cnum snum |

|---------------------------------------------------------------------------|

| 3001 Cisneros 2008 1007 |

| 3002 Pereira 2007 1004 |

| 3006 Cisneros 2008 1007 |

| 3009 Giovanni 2002 1003 |

| 3007 Grass 2004 1002 |

| 3010 Grass 2004 1002 |

=============================================

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

7.12. Объединение таблицы с собой

Методика объединения таблиц может использоваться для того, чтобы объединять вместе две копии одиночной таблицы.

При объединении таблицы с собой можно комбинировать каждую строку

таблицы и с собой, и с каждой другой строкой таблицы. Затем каждая комбинация оценивается в терминах предиката также, как при обьединении мультитаблиц.

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

таблицы. Это достигается с помощью определения временных имен, называемых переменными диапазона, переменными корреляции или просто псевдонимами; они определяются в предложении FROM запроса. Следует набрать имя таблицы, оставить пробел и затем набрать псевдоним для нее.

Например, найдем все пары заказчиков, имеющих один и тот

же рейтинг и живущих в одном городе:

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

FROM Customers first, Customers second

WHERE first.rating = second.rating AND first.city=second.city;

====== SQL Execution Log ==============

| Hoffman Hoffman 100 London |

| Hoffman Clemens 100 London |

| Clemens Hoffman 100 London |

| Clemens Clemens 100 London |

=====================================

Обратите внимание, что псевдонимы использованы уже в предложении SELECT до определения их в предложении FROM.

Псевдоним существует только на время выполнения команды !

Для устранения избыточности в выводе необходимо ввести дополнительный предикат.

Рассматриваемая особенность 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;

Вы можете использовать псевдонимы в любое время, когда вы хотите создать альтернативные имена для ваших таблиц в команде. Например, если ваши таблицы имеют очень длинные и сложные имена, вы могли бы определить простые односимвольные псевдонимы, типа a и b, и использовать их вместо имен таблицы в предложении SELECT и предикате.

Вы можете использовать любое число псевдонимов для одной таблицы в запросе.

Вы можете также создать обьединение, которое включает и различные таблицы, и псевдонимы одиночной таблицы.

Пусть задана следующая реляционная база данных.

Таблица Salespeople (Продавцы)

----------------------------------------------

SNUM | SNAME | CITY | COMM

---------|---------------|--------------|----------

1001 | Peel | London | .12

1002 | Serres | San Jose | .13

1004 | Motika | London | .11

1007 | Rifkin | Barcelona | .15

1003 | Axelrod | New York | .10

Таблица Customers (Заказчики)

-------------------------------------------------------------------------

CNUM | CNAME | CITY | RATING | SNUM

-----------|-----------------|----------------|----------------|----------

2001 | Hoffman | London | 100 | 1001

2002 | Giovanni | Rome | 200 | 1003

2003 | Liu | SanJose | 200 | 1002

2004 | Grass | Berlin | 300 | 1002

2006 | Clemens | London | 100 | 1001

2008 | Cisneros | SanJose | 300 | 1007

2007 | Pereira | Rome | 100 | 1004

Таблица Orders (Приобретения)

-----------------------------------------------

ONUM | AMT | ODATE | CNUM | SNUM

-----------|-----------------|----------------|----------------|------

3001 | 18.69 | 10/03/1990 | 2008 | 1007

3003 | 767.19 | 10/03/1990 | 2001 | 1001

3002 | 1900.10 | 10/03/1990 | 2007 | 1004

3005 | 5160.45 | 10/03/1990 | 2003 | 1002

3006 | 1098.16 | 10/03/1990 | 2008 | 1007

3009 | 1713.23 | 10/04/1990 | 2002 | 1003

3007 | 75.75 | 10/04/1990 | 2004 | 1002

3008 | 4723.00 | 10/05/1990 | 2006 | 1001

3010 | 1309.95 | 10/06/1990 | 2004 | 1002

3011 | 9891.88 | 10/06/1990 | 2006 | 1001

onum уникальный номер, присвоенный каждому приобретению.

amt значение суммы приобретений.

odate дата приобретения.

cnum номер заказчика, делающего приобретение (из таблицы Заказчиков ).

snum номер продавца, продающего приобретение ( из таблицы Продавцов).

Лекция 8. Подзапросы

8.1. Вставка одного запроса внутрь другого

С помощью SQL вы можете вкладывать запросы внутрь друга друга. Обычно, внутренний запрос генерирует значение, которое проверяется в предикате внешнего запроса, определяющего, истинно оно или нет.

Простой подзапрос выполняется только один раз.

Например, предположим что мы знаем имя продавца: Motika, но не знаем значение его поля snum, и хотим извлечь все приобретения из таблицы Приобретений. Запрос имеет следующую форму:

SELECT * FROM Orders

WHERE snum =( SELECT snum FROM Salespeople

WHERE sname = ‘Motika’);

Чтобы оценить внешний( основной ) запрос, SQL сначала должен оценить внутренний запрос ( или подзапрос ) внутри предложения WHERE.

Конечно же, подзапрос должен выбирать один и только один

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

выбранное поле и его значение будут иметь одинаковые имена( в этом

случае, snum ), но это необязательно.

Соседние файлы в предмете Базы данных