- •1.1. Технические параметры баз данных
- •1.2. Организация субд
- •1.6. Сетевая и иерархическая модели данных
- •1.7. Case - методы проектирования баз данных
- •1.8. Понятия “сущность” и “взаимосвязь”
- •4. Складывание.
- •5.3. Индексированные файлы
- •5.4. Операции с поиском по неключевым полям
- •6.2. Типы данных в sql
- •Int Число без десятичной точки. Эквивалентно decimal, но без
- •6.3. Обозначения в командах sql
- •6.... Оператор in
- •6.... Оператор between
- •6.... Оператор like
- •6.... Оператор is null
- •7.5... Скалярное выражение на основе выбранных полей
- •7.6... Упорядочение вывода полей
- •7.7.. Объединения нескольких таблиц в запросе
- •7.8.. Создание обьединения
- •7.9..Объединение таблиц через справочную целостность
- •7.10.. Объединения таблиц по равенству значений
- •7.11.. Объединение более двух таблиц
- •7.12. Объединение таблицы с собой
- •8.2. Значения, которые могут выдавать подзапросы
- •8.3. Предикаты с подзапросами являются необратимыми
- •8.4. Использование агрегатных функций в подзапросах
- •8.5. Использование подзапросов которые выдают
- •8.8. Подзапросы в предложении having
- •Insert into Londonstaff
- •Insert into Daytotals (date, total)
- •Insert для этой таблицы. Null - это наиболее широко используемое
- •1009, И Hoffman и Clemens будут также автоматически изменены.
- •Insert Пользователь с этой привилегией может выполнять
- •Insauth Имеет ли пользователь привилегию insert
- •Values ( :id_num, :salesperson, :loc, :comm)
- •Values (:id_num, :salesperson, :loc, :comm);
- •Into :id_num, :salesperson, :loc, :comm
- •Into :salesnum
- •1. Команда выполнилась без ошибки, но не произвела никакого
- •Into :id_num, :salesperson, :loc, :comm;
- •Indicator.
- •Indicator, связывая ее с каждой переменной главного языка, специальным способом, эмулирующим поведение null значений sql.
- •Values (:Id_num, :salesperson, :loc:i_a, :comm:i_b);
- •Indicator. Переменные indicator следуют за другим именами переменных в команде sql, без каких бы то ни было посторонних символов
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 ), но это необязательно.