Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базы данных.doc
Скачиваний:
114
Добавлен:
16.03.2016
Размер:
5.67 Mб
Скачать

18.2.12. Предикат is distinct

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

distinct_predicate ::= row_value_constructor IS DISTINCT FROM

row_value_constructor

Строки-операнды должны быть одинаковой степени. Типы данных соответствующих значений строк-операндов должны быть совместимы.

Напомним, что две строки s1с именами столбцовc1,c2, …,cnиs2с именами столбцовd1,d2, …,dnсчитаются строками-дубликатами, если для каждогоi( i = 1, 2, …, n) либоciиdiне содержатNULL, и(ci = di) = true, либо иci, иdiсодержатNULL. Значением условияs1 IS DISTINCT FROM s2являетсяtrueв том и только в том случае, когда строкиs1иs2не являются дубликатами. В противном случае значением условия являетсяfalse.

Заметим, что отрицательная форма условия – IS NOT DISTINCT FROM– в стандарте SQL не поддерживается. Вместо этого можно воспользоваться выражениемNOT s1 IS DISTINCT FROM s2.

Примеры запросов с использованием предиката distinct

Пример 18.28. Найти номера и имена служащих отдела 65, которых можно отличить по данным об имени и дате рождения от руководителя отдела 65.

SELECT EMP1.EMP_NO, EMP2.EMP_NO

FROM EMP EMP1, EMP EMP2

WHERE EMP1.EMP_NO <> EMP2.EMP_NO

AND NOT ((EMP1.EMP_NAME, EMP1.EMP_BDATE) IS DISTINCT FROM

(EMP2.EMP_NAME, EMP2.EMP_BDATE));

Пример 18.29. Найти все пары номеров таких служащих отдела 65, которых нельзя различить по данным об имени и дате рождения.

SELECT EMP_NO, EMP_NAME

FROM EMP

WHERE DEPT_NO = 65

AND (EMP_NAME, EMP_BDATE) IS DISTINCT FROM

(SELECT EMP1.EMP_NAME, EMP1.EMP_BDATE

FROM EMP EMP1, DEPT

WHERE EMP1.DEPT_NO = EMP.DEPT_NO

AND DEPT.DEPT_MNG = EMP1.EMP_NO);

18.3. Заключение

В этой лекции мы обсудили наиболее важные возможности языка SQL, связанные с выборкой данных. Даже простые примеры, приводившиеся в лекции, показывают исключительную избыточность языка SQL. Еще в то время, когда действующим стандартом языка был SQL/92, была опубликована любопытная статья, в которой приводилось 25 формулировок одного и того же несложного запроса. При использовании всех возможностей SQL:1999 этих формулировок было бы гораздо больше.

Можно спорить, хорошо или плохо иметь возможность формулировать один и тот же запрос десятками разных способов. На мой взгляд, это не очень хорошо, поскольку увеличивает вероятность появления ошибок в запросах (особенно в сложных запросах). С другой стороны, таково объективное состояние дел, и мы стремились обеспечить в этой лекции материал, достаточный для того, чтобы прочувствовать различные возможности формулировки запросов. Как показывают следующие две лекции, возможности, предоставляемые оператором SELECT, в действительности гораздо шире.

Лекция 19. Группировка и условия раздела having, порождаемые и соединенные таблицы

19.1. Введение

В предыдущих двух лекциях мы обсудили допускаемые в стандарте SQL виды ссылок на таблицы в разделе FROMоператораSELECTи подробно, с многочисленными примерами, рассмотрели возможные способы построения условных выражений разделаWHERE. Данную лекцию мы начинаем с анализа возможностей и целесообразности использования в запросах разделовGROUP BYиHAVING. Соответствующий раздел19.2 «Агрегатные функции, группировка и условия раздела HAVING»формально похож на раздел18.2 «Логические выражения раздела WHERE»лекции 18: обсуждаются виды предикатов, которые можно использовать в условных выражениях разделаHAVING, и приводятся иллюстрирующие примеры. Но в действительности мы преследуем большую цель: показать, что во многих случаях разделыGROUP BYиHAVINGявляются избыточными; запрос можно сформулировать более понятным образом без их использования. Применение разделовGROUP BYиHAVINGоказывается действительно полезным, а иногда и необходимым, в тех случаях, когда в запросе присутствует несколько вызовов агрегатных функций на группах строк.

После обсуждения разделов GROUP BYиHAVINGможно будет считать, что мы полностью рассмотрели базовые конструкции оператора выборки (разделORDER BYне заслуживает дополнительного обсуждения). Поэтому в разделах19.3. «Ссылки на порождаемые таблицы в разделе FROM»и19.4. «Более сложные конструкции оператора выборки»мы возвращаемся к отложенным в лекции 17 темам порождаемых таблиц, соединенных таблиц и порождаемых таблиц с горизонтальной связью.

В обычных порождаемых таблицах SQL нет ничего особенного. По всей видимости, возможность указывать в разделе FROMвыражения запросов, а не только ссылки на базовые или представляемые таблицы, была введена в SQL на основе следующих естественных соображений. Результатом вычисления выражения запросов в SQL является таблица. Следовательно, в любой конструкции языка, где может присутствовать ссылка на таблицу SQL, следует допустить присутствие выражения запросов. Одновременное наличие возможностей определения представляемых таблиц, указания именованного выражения запросов в разделеWITHи указания выражения запросов порождаемой таблицы непосредственно в списке разделаFROM, очевидно, является избыточным.

Соединенные таблицы появились еще в стандарте SQL/92, и внедрение в стандарт SQL этой возможности было действительно обоснованным. В соответствии с традиционной общей семантикой оператора SELECTв нем вообще не предусматривались явные средства для выражения потребности в соединении двух или более таблиц. Наличие возможности указывать несколько ссылок на таблицы в разделеFROMи спецификации произвольного логического выражения в разделеWHEREдля ограничения расширенного декартова произведения этих таблиц позволяет выражать с помощью традиционных средств SQL соединение общего вида в смысле Кодда, и до поры до времени это считалось достаточным.