KnigaRead.com/

Мартин Грубер - Понимание SQL

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мартин Грубер, "Понимание SQL" бесплатно, без регистрации.
Перейти на страницу:

2003

2008


Таблица 9.3 Комбинация пользователей с различными значениями рейтинга

Как вы можете видеть, этот запрос находит все комбинации заказчиков с тремя значениями оценки, поэтому первый столбец состоит из заказчиков с оценкой 100, второй с 200, и последний с оценкой 300. Они повторяются во всех возможных комбинациях. Это - сортировка группировки которая не может быть выполнена с GROUP BY или ORDER BY, поскольку они сравнивают значения только в одном столбце вывода.

Вы должны также понимать, что не всегда обязательно использовать каждый псевдоним или таблицу которые упомянуты в предложении FROM запроса, в предложении SELECT. Иногда, предложение или таблица становятся запрашиваемыми исключительно потому что они могут вызываться в предикате запроса. Например, следующий запрос находит всех заказчиков размещенных в городах где продавец Serres (snum 1002 ) имеет заказиков (вывод показывается в Таблице 9.4 ):


SELECT b.cnum, b.cname

FROM Customers a, Customers b

WHERE a.snum=1002

AND b.city=a.city;


SQL Execution Log

SELECT b.cnum, b.cname

FROM Customers a, Customers b

WHERE a.snum=1002 AND b.city=a.city;

cnum

cname

2003

Liu

2008

Cisneros

2004

Grass


Таблица 9.4 Нахождение заказчиков в городах относящихся к Serres.

Псевдоним a будет делать предикат неверным за исключением случая когда его значение столбца snum= 1002. Таким образом псевдоним опускает все, кроме заказчиков продавца Serres. Псевдоним b будет верным для всех строк с тем же самым значением города что и текущее значение города для a; в ходе запроса, строка псевдонима b будет верна один раз когда значение города представлено в a. Нахождение этих строк псевдонима b - единственая цель псевдонима a, поэтоиму мы не выбираем все столбцы подряд. Как вы можете видеть, собственные заказчики Serres вы бираются при нахождении их в том же самом городе что и он сам, поэтому выбор их из псевдонима a необязателен. Короче говоря, псевдоним назходит строки заказчиков Serres, Liu и Grass. Псевдоним b находит всех заказчиков размещенных в любом из их городов (San Jose и Berlin соответственно ) включая, конечно, самих - Liu и Grass.

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


SELECT sname, Salespeople.snum, first.cname

second.cname

FROM Customers first, Customers second, Salespeople

WHERE first.snum=second.snum

AND Salespeople.snum=first.snum

AND first.cnum < second.cnum;


SQL Execution Log

SELECT cname, Salespeople.snum, first.cname second.cname

FROM Customers first, Customers second, Salespeople

WHERE first.snum=second.snum AND Salespeople.snum=first.snum

AND first.cnum < second.cnum;

cname

snum

cname

cname

Serres

1002

Liu

Grass

Peel

1001

Hoffman

Clemens


Таблица 9.5: Объединение таблицы с собой и с другой таблицей

РЕЗЮМЕ

Теперь Вы понимаете возможности объединения и можете использовать их для ограничения связей с таблицей, между различными таблицами, или в обоих случаях. Вы могли видеть некоторые возможности объединения при использовании его способностей. Вы теперь познакомились с терминами порядковые переменные, корреляционные переменные и предложения (эта терминология будет меняться от изделия к изделию, так что мы предлагаем Вам познакомится со всеми тремя терминами). Кроме того Вы поняли, немного, как в действительности работают запросы.

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


РАБОТА С SQL

* Напишите запрос который бы вывел все пары продавцов живущих в одном и том же городе. Исключите комбинации продавцов с ними же, а также дубликаты строк выводимых в обратным порядке.

* Напишите запрос который вывел бы все пары порядков по данным заказчикам, именам этих заказчиков, и исключал дубликаты из вывода, как в предыдущем вопросе.

* Напишите запрос который вывел бы имена(cname) и города(city) всех заказчиков с такой же оценкой(rating) как у Hoffmanа. Напишите запрос использующий поле cnum Hoffmanа а не его оценку, так чтобы оно могло быть использовано если его оценка вдруг изменится.

Глава 10. ВСТАВКА ОДНОГО ЗАПРОСА ВНУТРЬ ДРУГОГО


В КОНЕЦ ГЛАВЫ 9, МЫ ГОВОРИЛИ ЧТО ЗАПРОСЫ могут управлять другими запросами. В этой главе, вы узнаете как это делается (большей частью), помещая запрос внутрь предиката другого запроса, и используя вывод внутреннего запроса в верном или неверном условии предиката. Вы сможете выяснить какие виды операторов могут использовать подзапросы и посмотреть как подзапросы работают со средствами SQL, такими как DISTINCT, с составными функциями и выводимыми выражения. Вы узнаете как использовать подзапросы с предложением HAVING и получите некоторые наставления как правильно использовать подзапросы.


КАК РАБОТАЕТ ПОДЗАПРОС?

С помощью SQL вы можете вкладывать запросы внутрь друга друга. Обычно, внутренний запрос генерирует значение которое проверяется в предикате внешнего запроса, определяющего верно оно или нет. Например, предположим что мы знаем имя продавца: Motika, но не знаем значение его поля snum, и хотим извлечь все порядки из таблицы Порядков. Имеется один способ чтобы сделать это( вывод показывается в Таблице 10.1 ):


SELECT *

FROM Orders

WHERE snum=

( SELECT snum

FROM Salespeople

WHERE sname='Motika');


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

Единственной найденной строкой естественно будет snum=1004. Однако SQL, не просто выдает это значение, а помещает его в предикат основного запроса вместо самого подзапроса, так чтобы предиката прочитал что


WHERE snum=1004


SQL Execution Log

SELECT * FROM Orders WHERE snum=

(SELECT snum FROM Salespeople WHERE sname='Motika');

onum

amt

odate

cnum

snum

3002

1900.10

10/03/1990

2007

1004


Таблица 10.1: Использование подзапроса

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

Конечно, если бы мы уже знали номер продавца Motika, мы могли бы просто напечатать

WHERE snum=1004

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


ЗНАЧЕНИЯ, КОТОРЫЕ МОГУТ ВЫДАВАТЬ ПОДЗАПРОСЫ

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

Имея выбранным поле snum " WHERE city="London" вместо "WHERE sname='Motika", можно получить несколько различных значений. Это может сделать уравнение в предикате основного запроса невозможным для оценки верности или неверности, и команда выдаст ошибку.

При использовании подзапросов в предикатах основанных на реляционных операторах (уравнениях или неравенствах, как объяснено в Главе 4 ), вы должны убедиться что использовали подзапрос который будет выдавать одну и только одну строку вывода. Если вы используете подзапрос который не выводит никаких значений вообще, команда не потерпит неудачи; но основной запрос не выведет никаких значений. Подзапросы которые не производят никакого вывода (или нулевой вывод) вынуждают рассматривать предикат ни как верный ни как неверный, а как неизвестный. Однако, неизвестный предикат имеет тот же самый эффект что и неверный: никакие строки не выбираются основным запросом (смотри Главу 5 для подробной информации о неизвестном предикате ).

Это плохая стратегия, чтобы делать что-нибудь подобное следующему:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*