DISTINCT С ПОДЗАПРОСАМИ
Вы можете, в
некоторых случаях, использовать DISTINCT чтобы вынудить подзапрос генерировать одиночное значение.
Предположим
что мы хотим найти все порядки кредитований для тех продавцов которые обслуживают Hoffmanа ( cnum = 2001 ).
Имеется
один способ чтобы сделать это ( вывод показывается в Рисунке 10.2 ):
SELECT * FROM Orders WHERE snum = ( SELECT DISTINCT snum FROM Orders WHERE cnum = 2001 );
onum |
amt |
odate |
cnum |
snum |
3003 |
767.19 |
10/03/1990 |
2001 |
1001 |
3008 |
4723.00 |
10/05/1990 |
2006 |
1001 |
3011 |
4723.00 |
10/06/1990 |
2006 |
1001 |
Рисунок 10.2: Использование DISTINCT чтобы вынудить получение одного значения из подзапроса
Подзапрос установил что значение поля snum совпало с Hoffman - 1001, и затем
основной запрос выделил все порядки с этим значением snum из таблицы Порядков( не разбирая, относятся они
к Hoffman
или нет). Так как каждый заказчик назначен к одному и только этому продавцу, мы знаем что каждая строка в таблице
Порядков с данным значением cnum должна иметь такое же значение snum. Однако так как там может быть любое
число
таких строк, подзапрос мог бы вывести много ( хотя и идентичных ) значений snum для данного поля cnum. Аргумент
DISTINCT предотвращает это. Если наш подзапрос возвратит более одного значения, это будет указывать на ошибку
в наших
данных - хорошая вещь для знающих об этом. Альтернативный подход должен быть чтобы ссылаться к таблице Заказчиков
а
не к таблице Порядков в подзапросе. Так как поле cnum - это первичный ключ таблицы Заказчика, запрос выбирающий
его
должен произвести только одно значение. Это рационально только если вы как пользователь имеете доступ к
таблице
Порядков но не к таблице Заказчиков. В этом случае, вы можете использовать решение которое мы показали выше.
( SQL
имеет механизмы которые определяют - кто имеет привилегии чтобы делать что-то в определенной таблице. Это
будет
объясняться познее.) Пожалуйста учтите, что методика используемая в предшествующем примере применима только
когда вы знаете, что два различных поля в таблице должны всегда совпадать, как в нашем случае. Эта ситуация
не является
типичной в реляционных базах данных, она являеться исключением из правил.