Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
536.pdf
Скачиваний:
1
Добавлен:
15.11.2022
Размер:
2.31 Mб
Скачать

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

6.2.8. Условия поиска групп HAVING. Точно так же, как предложение WHERE, используется для отбора отдельных строк, участвующих в запро­ се, предложение HAVING можно применить для отбора групп строк. Его формат соответствует формату предложения WHERE. Предложение HAV­ ING состоит из ключевого слова HAVING, за которым следует условие поиска. Таким образом, данное предложение определяет условие поиска для групп. Основным отличием предложения HAVING от WHERE в том, что оно применяется уже непосредственно после самого запроса и в усло­ вие поиска включается поле с примененной к нему агрегатной функцией.

Вывести те дни месяца, когда оборот превышал 1000 руб. :

SELECT ДАТА_ДОК, SUM (КОЛ-ВО*ЦЕНА) SUM (КОЛ-ВО*ЦЕНА)

FROM ПЕРЕМЕЩЕНИЕ

WHERE ДАТА_ДОК BETWEEN ‘1.01.2000’ AND ’31.01.2000’ GROUP BY ДАТА_ДОК

HAVING SUM (КОЛ-ВО*ЦЕНА)> 1000

Вывести все идентификаторы городов, если количество клиентов из них больше трех:

SELECT IDN_ГОРОДА FROM КЛИЕНТ

GROUP BY IDN_TOPOM HAVING COUNT(*) >3

6.3. Работа с несколькими таблицами

6.3.1. Объединение при помощи оператора WHERE. На практике мно гие запросы считывают данные сразу из нескольких таблиц базы данных. Например, у нас существуют две таблицы:

Таблица Города

IDN

НАЗВАНИЕ

100

Москва

102Санкт-Петербург

103Пермь

105 Париж

IDN

НАЗВАНИЕ(ИМЯ)

IDN ГОРОДА

1

МММ

100

2

Хопер

100

3

Алиса

102

4

иве

103

5

ПГТУ

103

6

Рога&Копыта

 

Вывести всех клиентов с указанием города:

SELECT ГОРОДА.НАЗВАНИЕ, КЛИЕНТ.НАЗВАНИЕ(ИМЯ) FROM ГОРОДА,КЛИЕНТ

WHERE ГОРОДА.IDN=KЛИЕНТ.ШМ_ГОРОДА

Результат этого запроса:

Москва

МММ

Москва

Хопер

Санкт-

Алиса

Петербург

 

Пермь

и в е

Пермь

ПГТУ

Если бы нам нужны были клиенты только из Москвы, то этот запрос до­ полнился бы еще одной строкой:

AND ГОРОДА-НАЗВАНИЕ =’Москва’

В качестве упрощенного варианта этот же запрос можно записать сле­ дующим образом:

SELECT Г.НАЗВАНИЕ, К.НАЗВАНИЕ(ИМЯ) FROM ГОРОДА Г., КЛИЕНТ К.

WHERE r.IDN=K.IDN_rOPOM AND Г.НАЗВАНИЕ=’Москва’

Нас интересует, на какую сумму был оборот по каждой группе товаров за какой-то промежуток времени:

SELECT ГР.НАЗВАНИЕ, 8ЦМ(П.КОЛ-ВО*П.ЦЕНА) FROM ГРУППЫ ГР., ПЕРЕМЕЩЕНИЕ П.

WHERE rP.IDN=n.IDN_rpyimbI AND П.ДАТА_ДОК

BETWEEN ‘1.02.2000’ AND ’16.03.2000’

GROUP BY ГР.НАЗВАНИЕ

HAVING 8ЦМ(П.КОЛ-ВО*П.ЦЕНА)> 1000 ORDER BY 8иМ(П.КОЛ-ВО*П.ЦЕНА)

6.3.2.Внутренние и внешние объединения. Примеры, рассмотренные

впредыдущем разделе, формально относятся к так называемым внутрен­ ним объединениям. Внутреннее объединение возвращает строки, только если условие объединения выполнено. Приведем еще раз пример запроса с использованием оператора JOIN (соединять).

Вывести всех клиентов с указанием города:

SELECT ГОРОДА-НАЗВАНИЕ, КЛИЕНТ.НАЗВАНИЕ(ИМЯ) FROM ГОРОДА

INNER JOIN КЛИЕНТ ON ГОРОДАЛО^КЛИЕНТЛО^ГОРОДА

Результат этого запроса:

Москва

МММ

Москва

Хопер

Санкт-Петербург

Алиса

Пермь

иве

Пермь

ПГТУ

Обратите внимание, что ни город Париж, ни клиент Рога&Копыта в результаты запроса не попали.

На то, что мы имеем дело с внутренним объединением, указывает ключевое слово INNER (внутренний). Помимо внутренних объединений часто имеет смысл использовать внешние объединения, которые возвра­ щают строки независимо от того, выполнено условие объединения или нет. Когда условие объединения не выполнено для данной строки во внешнем объединении, поля из внутренней таблицы возвращаются, как

NULL.

Различают правые и левые внешние объединения, которые различа­ ются тем, из какой таблицы (внутренней или внешней) извлекаются все строки. Приведем примеры.

Левое внешнее объединение.

Вывести всех клиентов, если для клиента указан город, показать его:

SELECT ГОРОДА.НАЗВАНИЕ, KJMEHT.HA3BAHHE(HMiI)

FROM ГОРОДА

LEFT OUTER JOIN КЛИЕНТ ON ГОРОДА.Ш^КЛИЕНТ.ГО^ГОРОДА

Результат этого запроса:

Москва

МММ

Москва

Хопер

Санкт-Петербург

Алиса

Пермь

иве

Пермь

ПГТУ

 

Рога&Копыта

Обратите внимание, что был выведен клиент Рога&Копыта, для кото­ рого город не указан.

В этом запросе были использованы ключевые слова LEFT (левый) OUTER (внешний).

Правое внешнее объединение.

Вывести все города и всех клиентов из этих городов:

SELECT ГОРОДА.НАЗВАНИЕ, КЛИЕНТ.НАЗВАНИЕ(ИМЯ) FROM ГОРОДА

RIGHT OUTER JOIN КЛИЕНТ ON rOPO/(A.IDN=KJIHEHT.IDN_rOPO<aA

Результат этого запроса:

Москва

МММ

Москва

Хопер

Санкт-Петербург

Алиса

Пермь

иве

Пермь

ПГТУ

Париж

 

Врезультате теперь присутствует Париж.

6.4.Вложенные запросы

6.4.1. Исходная база данных. Эта база данных далее будет использо­ ваться в примерах.

Таблица Клиент

IDN IDN ГОРОДА имя

РЕКВИЗИТ IDN БАНКА

204

101

Петров

311

205

104

Кузнецов

 

314

206

102

Иванов

 

317

208

104

Золин

 

311

210

105

Киров

 

323

212

103

Павлов

 

317

215

105

| Петренко

 

318

Таблица Города

IDN НАЗВАНИЕ

102Минск

101Москва

103Саратов 104 Пермь 105 Киев

IDN РЕКВИЗИТЫ 311 МММ

314 Альфабанк

317Сбербанк

323Менатеп

318Западуралбанк

Таблица Перемещение

IDN ПОРЯД­

КОВ №

о О

Д А Т А .

НО­

IDN

IDN

к о л -

ЦЕ­

ДОК

МЕР

ГРУП­

МАТ.

в о

НА

 

д о к

ПЫ

ЦЕН.

 

 

 

 

402

501

 

20

 

 

402

503

 

25

 

 

404

505

 

6

 

 

404

504

 

7

 

 

404

506

 

5

 

 

406

508

 

15

 

 

406

507

 

25

Некоторые столбцы не заполнены, т.к. не используются в примерах.

Таблица Группы

IDN НАЗВАНИЕ 402 Газ. вода 404 Шоколад 406 Сигареты

Таблица Мат. ценности

 

IDN ГРУППЫ

IDN МАТ.ЦЕН.

IDN МАТ.ЦЕН.

402

501

Fanta

402

503

Sprite

404

505

Mars

404

504

Twix

404

506

Шок

406

508

Кама

406

507

L&M

6.4.2. Вложение запросов. SQL позволяет вкладывать запросы друг в друга. Внешний запрос использует значения, которые генерируются во внутреннем запросе. Предположим, необходимо извлечь всю информа­ цию о банке, с которым работает Киров. Вот один из способов решения:

SELECT * FROM БАНКИ

WHERE IDN =(SELECT IDN_EAHKA FROM КЛИЕНТ WHERE ИМЯ=‘Киров’)

Выходные данные: IDN РЕКВИЗИТ 323 Менатеп

Чтобы оценить основной запрос, SQL должен оценить внутренний запрос (или подзапрос) в предложении WHERE Подзапрос оценивается так, как если бы он был основным запросом: просматриваются все стро­ ки таблицы Клиент и выбираются те строки, для которых значение поля Имя равно Киров, для таких строк выбираются значения поля IDNJSAHKA.

В результате выбранной оказывается строка с IDN_BAHKA = 323. SQL подставляет его в предикат основного запроса вместо подзапроса, теперь предикат читается следующим образом:

WHERE IDN =323

После этого основной запрос выполняется как обычный, его результат показан выше.

Если указать просто:

WHERE IDN =323

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

В следующем примере использование подзапроса обязательно.

Получить все банки, которые не используются клиентами:

SELECT * FROM Банки

WHERE (SELECT COUNT(*) FROM Клиент WHERE Клиент.ГОИ_банка = Банки-IDN) = О

\Подзапрос возвращает количество клиентов для каждого ЮЫ_банка из внешнего запроса. Внешний запрос выдает только те банки, для которых это количество равно нулю._______________________________

Еще один пример, когда необходимо использовать подзапрос:

Для каждой группы товаров найти товар с минимальной ценой, вывести название группы, название товара, цену:

Проверка - работает ли кто-нибудь с банком МММ (код 311).

SELECT Г.НАЗВАНИЕ, M НАЗВАНИЕ, П.ЦЕНА

FROM Группы Г, МАТ.ЦЕННОСТИ М, ПЕРЕМЕЩЕНИЕ П WHERE M.IDN ГРУППЫ = n.IDN ГРУППЫ

AND M.IDN МАТ.ЦЕН. = n.IDN

МАТ.ПЖ

 

AND r.IDN = n.ID N ГРУППЫ

j Эти три

подчеркнутых равенства

 

связывают

таблицы между собой,

AND П.ИЕНА = fSELECT MIN ШЕНА)

т.к. надо получить в результате на­

FROM Перемещение ПВНУТР

звание, а в таблице Перемещение

WHERE n.ID N ГРУППЫ =

хранятся только идентификаторы.

 

ПВНУТР.ПЖ ГРУППЫ) ч

 

'Это равенство связывает цену из внешнего запроса с минимальной ценой для каждой группы, найденной в подзапросе.

6.4.3.Оператор EXISTS. EXISTS (существует ) - оператор, генери­ рующий значения «истина» или «ложь». Его можно применять отдельно в предикате или комбинировать с другими выражениями с помощью опера­ торов AND, OR, NOT. Этот оператор оценивает подзапрос как истинный, если подзапрос генерирует выходные данные, а в противном случае - как ложный, иными словами, оператор EXISTS возвращает значение «истина», если подзапрос возвращает хотя бы одну строку. В отличие от прочих операторов и предикатов, он не может принимать значения unknown (не­ известный). Например, нужно извлечь данные из таблицы Клиент в том случае, если один (или более) клиент из нее работает с банком МММ:

SELECT * FROM КЛИЕНТ , WHERE EXISTS

(SELECT* FROM КЛИЕНТ WHERE НЖ_банка = 311)

Выходные данные:

 

 

IDN

IDN ГОРОД] ИМЯ

РЕКВИЗИТЫ IDN БАНКА

204

101

Петров

311

205

104

Кузнецов

314

206

102

Иванов

317

208

104

Золин

311

210

105

Киров

323

212

103

Павлов

317

215

105

Петренко

318

Внутренний запрос выбрал все данные обо всех клиентах, работаю­ щих с МММ. Т.к. такие клиенты существуют, оператор EXISTS отметил, что подзапрос генерирует выходные данные и принимает значение «исти­ на». В данном случае тот же результат можно было получить проще, одна­ ко бывают случаи, когда без EXISTS не обойтись:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]