Чтение онлайн

на главную

Жанры

Понимание SQL

Грубер Мартин

Шрифт:

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

SELECT snum, sname

FROM Salespeople main

WHERE 1 <

( SELECT COUNT (*)

FROM Customers

WHERE snum=main.snum );

Обратите внимание что предложение FROM подзапроса в этом примере не использует псевдоним. При отсутствии имени таблицы или префикса псевдонима, SQL может для начала принять, что любое поле выводится из таблицы с именем указанным в предложении FROM текущего запроса. Если поле с этим именем отсутствует( в нашем случае - snum ) в той таблице, SQL будет проверять внешние запросы. Именно поэтому, префикс имени таблицы обычно необходим в соотнесенных подзапросах - для отмены этого предположения. Псевдонимы также часто запрашиваются чтобы

давать вам возможность ссылаться к той же самой таблице во внутреннем и внешнем запросе без какой-либо неоднозначности.

SQL Execution Log

SELECT snum sname FROM Salespeople main

WHERE 1 < AND second.odate=10/03/1990;

cnum

cname

city

rating

snum

2001

Hoffman

London

100

1001

2003

Liu

San Jose

200

1002

2008

Cisneros

San Jose

300

1007

2007

Pereira

Rome

100

1004

Таблица 11.3: Нахождение продавцов с многочислеными заказчиками

ИСПОЛЬЗОВАНИЕ СООТНЕСЕННЫХ ПОДЗАПРОСОВ ДЛЯ НАХОЖДЕНИЯ ОШИБОК

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

SELECT *

FROM Orders main

WHERE NOT snum=

( SELECT snum

FROM Customers

WHERE cnum=main.cnum );

При использовании механизма справочной целостности (обсужденного в Главе 19 ), вы можете быть гарантированы от некоторых ошибок такого вида. Этот механизм не всегда доступен, хотя его использование желательно во всех случаях, причем поиск ошибки запроса описанный выше, может быть еще полезнее.

СРАВНЕНИЕ ТАБЛИЦЫ С СОБОЙ

Вы можете также использовать соотнесенный подзапрос основанный на той же самой таблице что и основной запрос. Это даст вам возможность извлечть определенные сложные формы произведенной информации. Например, мы можем найти все порядки со значениями сумм приобретений выше среднего для их заказчиков (вывод показан в Таблице 11.4 ):

SELECT *

FROM Orders outer

WHERE amt >

( SELECT AVG amt

FROM Orders inter

WHERE inner.cnum=outer.cnum );

SQL Execution Log

SELECT * FROM Orders outer WHERE amt >

(SELECT AVG (amt) FROM Orders inner

WHERE inner.cnum=outer.cnum

onum

amt

odate

cnum

snum

3006

1098.19

10/03/1990

2008

1007

3010

1309.00

10/06/1990

2004

1002

3011

9891.88

10/06/1990

2006

1001

Таблица 11.4: Соотнесение таблицы с собой

Конечно, в нашей маленькой типовой таблице, где большиство заказчиков имеют только один порядок, большинство значений являются одновременно средними и следовательно не выбираются. Давайте введем команду другим способом (вывод показывается в Таблице 11.5):

SELECT *

FROM Orders outer

WHERE amt >=

( SELECT AVG (amt)

FROM Orders inner

WHERE inner.cnum=outer.cnum );

SQL Execution Log

SELECT * FROM Orders outer WHERE amt > =

(SELECT AVG (amt) FROM Orders inner

WHERE inner.cnum=outer.cnum);

onum

amt

odate

cnum

snum

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.19

10/03/1990

2008

1007

3009

1713.23

10/04/1990

2002

1003

3010

1309.95

10/06/1990

2004

1002

3011

9891.88

10/06/1990

2006

1001

Таблица 11.5: Выбераются порядки которые >=средней сумме приобретений для их заказчиков.

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

СООТНЕСЕННЫЕ ПОДЗАПРОСЫ В ПРЕДЛОЖЕНИИ HAVING

Также как предложение HAVING может брать подзапросы, он может брать и соотнесенные подзапросы. Когда вы используете соотнесенный подзапрос в предложении HAVING, вы должны ограничивать внешние ссылки к позициям которые могли бы непосредственно использоваться в самом предложении HAVING. Вы можете вспомнить из Главы 6 что предложение HAVING может использовать только агрегатные функции которые указаны в их предложении SELECT или поля используемые в их предложении GROUP BY. Они являются только внешними ссылками, которые вы можете делать. Все это потому, что предикат предложения HAVING оценивается для каждой группы из внешнего запроса, а не для каждой строки. Следовательно, подзапрос будет выполняться один раз для каждой группы выведеной из внешнего запроса, а не для каждой строки.

Предположим что вы хотите суммировать значения сумм приобретений покупок из таблицы Порядков, сгруппировав их по датам, удалив все даты где бы SUM не был по крайней мере на 2000.00 выше максимальной (MAX ) суммы:

SELECT odate, SUM (amt)

FROM Orders a

GROUP BY odate

HAVING SUM (amt) >

( SELECT 2000.00 + MAX (amt)

FROM Orders b

WHERE a.odate=b.odate );

Подзапрос вычисляет значение MAX для всех строк с той же самой датой что и у текущей агрегатной группы основного запроса. Это должно быть выполнено, как и ранее, с испошльзованием предложения WHERE. Сам подзапрос не должен использовать предложения GROUP BY или HAVING.

Поделиться:
Популярные книги

Внебрачный сын Миллиардера

Громова Арина
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Внебрачный сын Миллиардера

Вечная Война. Книга VII

Винокуров Юрий
7. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
5.75
рейтинг книги
Вечная Война. Книга VII

Калибр Личности 1

Голд Джон
1. Калибр Личности
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Калибр Личности 1

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Отмороженный 3.0

Гарцевич Евгений Александрович
3. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 3.0

Довлатов. Сонный лекарь 3

Голд Джон
3. Не вывожу
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь 3

Мама из другого мира. Дела семейные и не только

Рыжая Ехидна
4. Королевский приют имени графа Тадеуса Оберона
Любовные романы:
любовно-фантастические романы
9.34
рейтинг книги
Мама из другого мира. Дела семейные и не только

Болотник

Панченко Андрей Алексеевич
1. Болотник
Фантастика:
попаданцы
альтернативная история
6.50
рейтинг книги
Болотник

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

Назад в ссср 6

Дамиров Рафаэль
6. Курсант
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Назад в ссср 6

Лучший из худших

Дашко Дмитрий
1. Лучший из худших
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Лучший из худших

Ротмистр Гордеев 2

Дашко Дмитрий
2. Ротмистр Гордеев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев 2

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Темный Патриарх Светлого Рода 7

Лисицин Евгений
7. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 7