Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SQL.doc
Скачиваний:
19
Добавлен:
14.03.2016
Размер:
382.46 Кб
Скачать

Предложение having

Если предложение WHERE определяет предикат для фильтрации строк, то предложение HAVING применяется после группировки для определения аналогичного предиката, фильтрующего группы по значениям агрегатных функций. Это предложение необходимо для проверки значений, которые получены с помощью агрегатной функции не из отдельных строк источника записей, определенного в предложении FROM, а из групп таких строк. Поэтому такая проверка не может содержаться в предложении WHERE.

Пример: Получить количество ПК и среднюю цену для каждой модели, средняя цена которой менее $800

  1. SELECT model,COUNT(model) AS Qty_model,AVG(price) AS Avg_price

  2. FROM PC

  3. GROUP BY model

  4. HAVING AVG(price) < 800;

Заметим, что в предложении HAVING нельзя использовать псевдоним (Avg_price), используемый для именования значений агрегатной функции в предложении SELECT. Дело в том, что предложение SELECT, формирующее выходной набор запроса, выполняется предпоследним перед предложением ORDER BY. Ниже приведен порядок обработки предложений в операторе SELECT:

  1. FROM

  2. WHERE

  3. GROUP BY

  4. HAVING

  5. SELECT

  6. ORDER BY

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

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

Использование в запросе нескольких источников записей

Как видно из приведенной в конце предыдущего раздела синтаксической формы оператора SELECT, в предложении FROM допускается указание нескольких таблиц. Простое перечисление таблиц через запятую практически не используется, поскольку оно соответствует реляционной операции, которая называется декартовым произведением. То есть в результирующем наборе каждая строка из одной таблицы будет сочетаться с каждой строкой из другой. 

Например, для таблиц:

A

a

b

1

2

2

1

B

c

d

2

4

3

3

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

  1. SELECT *

  2. FROMA, B;

будет выглядеть следующим образом:

a

b

c

d

1

2

2

4

1

2

3

3

2

1

2

4

2

1

3

3

Поэтому перечисление таблиц, как правило, используется совместно с условием соединения строк из разных таблиц, указываемым в предложении WHERE. Для приведенных выше таблиц таким условием может быть совпадение значений, скажем, в столбцах a и c:

  1. SELECT *

  2. FROM A, B

  3. WHERE a = c;

Теперь результатом выполнения этого запроса будет следующая таблица:

a

b

c

d

2

1

2

4

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

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

<имя таблицы>.<имя столбца>

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

Пример1: Найти номер модели и производителя ПК, имеющих цену менее $600:

  1. SELECT DISTINCT PC.model, maker

  2. FROM PC, Product

  3. WHERE PC.model = Product.model AND

  4. price < 600;

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

Иногда в предложении FROM требуется указать одну и ту же таблицу несколько раз. В этом случае обязательным является переименование.

Пример2: Вывести пары моделей, имеющих одинаковые цены:

  1. SELECT DISTINCT A.model AS model_1, B.model AS model_2

  2. FROM PC AS A, PC B

  3. WHERE A.price = B.price AND

  4. A.model < B.model;

Переименование также является обязательным, если в предложении FROM используется подзапрос, так как, в противном случае, у нас нет возможности уточнения имени столбца из подзапроса. Так, первый пример можно переписать следующим образом:

  1. SELECT DISTINCT PC.model, maker

  2. FROM PC, (SELECT maker, model

  3. FROM Product

  4. ) AS Prod

  5. WHERE PC.model = Prod.model AND

  6. price < 600;

Обратите внимание, что в этом случае в других предложениях оператора SELECT уже нельзя использовать квалификатор Product, поскольку таблица Product уже не используется. Вместо него используется псевдоним Prod. Кроме того, ссылаться извне теперь можно только на те столбцы таблицы Product, которые перечислены в подзапросе.

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

  1. SELECT DISTINCT model, maker

  2. FROM PC, (SELECT maker, model

  3. FROM Product

  4. ) AS Prod(maker, model_1)

  5. WHERE model = model_1 AND

  6. price < 600;

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