Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методическое пособие 522

.pdf
Скачиваний:
6
Добавлен:
30.04.2022
Размер:
2.03 Mб
Скачать

Результатом служит копия полной таблицы S.

Здесь звезда или звездочка служит кратким обозначением списка всех имен полей в таблице (таблицах), указанной(ых) во фразе FROM (из) в том порядке, в котором эти поля определяются в соответствующем(их) предложении(ях) CREATE TABLE. Таким образом, записанное выше предложение SELECT эквивалентно следующему:

SELECT НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, ГОРОД

FROM S;

Обозначение в виде звездочки удобно для интерактивных запросов, поскольку оно уменьшает число ударов по клавишам. Однако оно таит потенциальную опасность при использовании во встроенном SQL (т. е. в предложениях SQL в прикладной программе), поскольку смысл знака «*» может измениться, если для этой программы перегенерируется план прикладной задачи, а в данном промежутке времени к рассматриваемой таблице был добавлен другой столбец. В этом пособии «SELECT *» будет использоваться только в таких контекстах, где так делать безопасно (в основном только в интерактивных контекстах), и фактическим пользователям рекомендуется поступать подобным образом.

Отметим, наконец, что «*» может уточняться именем соответствующей таблицы. Допустима, например, следующая форма записи:

SELECT S.*

FROM S;

Ограниченная выборка

Выдать номера поставщиков, которые находятся в Париже и имеют состояние большее, чем 20:

241

SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE ГОРОД = ’Париж’

AND СОСТОЯНИЕ > 20;

Результат:

НОМЕР_ПОСТАВЩИКА

S3

Условие, или предикат, следующий за ключевым словом WHERE, может включать операторы сравнения =, != (неравно), >, > =, <, и <=, булевские операторы AND (и), OR (или) и NOT (нет), а скобки указывают требуемый порядок вычислений. В таком предикате числа сравниваются алгебраически — отрицательные числа считаются меньшими, чем положительные, независимо от их абсолютной величины. Строки литер сравниваются в соответствии с их представлением в коде ASCII. Если нужно сравнить две строки литер, имеющих разные длины, более короткая строка концептуально дополняется справа пробелами для того, чтобы обе строки имели одинаковую длину перед тем, как будет осуществляться их сравнение.

Выборка с упорядочением

Выдать номера и состояния поставщиков, находящихся в Париже, в порядке убывания их состояния:

SELECT НОМЕР_ПОСТАВЩИКА, СОСТОЯНИЕ

FROM S

WHERE ГОРОД = ’Париж’

ORDER BY СОСТОЯНИЕ DESC;

Результат:

 

НОМЕР_ПОСТАВЩИКА

СОСТОЯНИЕ

S3

30

S2

10

242

В общем случае не гарантируется, что результирующая таблица будет упорядочена каким-либо определенным образом. Здесь, однако, пользователь специфицировал, что результат перед тем, как он будет показан, должен быть организован в определенной последовательности. Упорядочение может быть специфицировано таким же образом, как в предложении

CREATE INDEX:

имя—столбца [упорядочение] [, имя—столбца [упорядочение]] ...,

где «упорядочение», как и ранее, это ASC (возрастание) или DECS (убывание), и по умолчанию принимается ASC. Каждое «имя—столбца» должно идентифицировать некоторый столбец результирующей таблицы. Поэтому, например, следующее предложение недопустимо:

SELECT НОМЕР_ПОСТАВЩИКА

FROM S

ORDER BY ГОРОД;

Разрешается также идентифицировать столбцы во фразе ORDER BY (упорядочить по) «номерами—столбцов» вместо «имен—столбцов», где «номер—столбца» указывает порядковую позицию (слева направо) данного столбца в результирующей таблице запроса. Благодаря этому возможно упорядочение результата на основе «вычисляемых столбцов», которые не обладают именем. Например, упорядочить результат по возрастанию номера детали в рамках возрастания веса в граммах:

SELECT НОМЕР_ДЕТАЛИ, ВЕС*454

FROM P

ORDER BY 2, НОМЕР_ДЕТАЛИ; [или ORDER BY 2,1;]

Здесь «2» ссылается на второй столбец результирующей таблицы.

243

Получаем:

НОМЕР_ДЕТАЛИ

P1

5448

P5

5448

P4

6356

P2

7718

P3

7718

P6

8626

Выборка с использованием between (между)

Выдать сведения о деталях, вес которых находится в диапазоне от 16 до 19 включительно:

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM P

WHERE ВЕС BETWEEN 16 AND 19;

Имеем следующий результат:

 

 

НОМЕР_

НАЗВАНИЕ

ЦВЕТ

ВЕС

ГОРОД

ДЕТАЛИ

 

 

 

 

P2

Болт

З

17

Париж

 

 

еленый

 

 

P3

Винт

Голубой

17

Рим

P6

Блюм

Красный

19

Лондон

Может быть также специфицировано NOT BETWEEN (не принадлежит диапазону между), например:

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM P

WHERE ВЕС NOT BETWEEN 16 AND 19;

244

Получаем тогда:

 

 

 

НОМЕР_

НАЗВАНИЕ

ЦВЕТ

ВЕС

ГОРОД

ДЕТАЛИ

 

 

 

 

P1

Гайка

Красный

12

Лондон

P4

Винт

Красный

14

Лондон

P5

Кулачок

Голубой

12

Париж

Выборка с использованием in (принадлежит)

Выдать детали, вес которых равен 12, 16 или 17:

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM Р

WHERE ВЕС IN (12, 16, 17);

Результат:

 

 

 

НОМЕР_

НАЗВАНИЕ

ЦВЕТ

ВЕС

ГОРОД

ДЕТАЛИ

 

 

 

 

P1

Гайка

Красный

12

Лондон

P2

Болт

Зеленый

17

Париж

P3

Винт

Голубой

17

Рим

P5

Кулачок

Голубой

12

Париж

Предикат IN является в действительности просто краткой записью предиката, представляющего собой последовательность отдельных сравнений, соединенных операторами OR (или). Предыдущее предложение SELECT эквивалентно следующему:

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM Р WHERE ВЕС = 12 OR ВЕС = 16

OR ВЕС = 17;

245

Имеется в распоряжении также предикат NOT IN (не принадлежит), например предложение;

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM P

WHERE ВЕС NOT IN (12, 16, 17);

дает результат

 

 

 

 

НОМЕР_

НАЗВАНИЕ

ЦВЕТ

ВЕС

ГОРОД

ДЕТАЛИ

 

 

 

 

P4

Винт

Красный

14

Лондон

P6

Блюм

Красный

19

Лондон

Подобно предикату IN предикат NOT IN может рассматриваться только как сокращенная запись другого предиката, который не использует NOT IN. Упражнение. Запишите «развернутую форму» предложения из предшествующего примера.

Выборка с использованием предиката like (похоже на)

Выдать все детали, названия которых начинаются с буквы «С»:

SELECT НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД

FROM P

WHERE НАЗВАНИЕ LIKE ’С%’;

Получаем результат:

 

 

 

НОМЕР_

НАЗВАНИЕ

ЦВЕТ

ВЕ

ГОРОД

ДЕТАЛИ

 

 

С

 

P5

Кулачок (Cam)

Голубой

12

Париж

P6

Блюм (Cog)

Красный

19

Лондон

246

Обычно предикат LIKE имеет форму:

имя—столбца LIKE литерная—строковая—константа, где «имя—столбца» должно обозначать столбец типа CHAR или VARCHAR. Этот предикат принимает для заданной записи значение истина, если значение в указанном столбце соответствует образцу, специфицируемому «литерной— строковой—константой». Литеры этой константы интерпретируются следующим образом:

-Литера «_» (разрыв или подчеркивание) обозначает

любую одиночную литеру.

-Литера «%» (процент) обозначает любую последовательность из n литер (где n может быть нулем).

-Все другие литеры обозначают просто сами себя. Следовательно, в приведенном примере предложение

SELECT будет осуществлять выборку записей из таблицы P, для которых значение в столбце НАЗВАНИЕ начинается буквой «С» и содержит любую последовательность из нуля или более литер, следующую за этой буквой «С».

Ниже приведено еще несколько примеров, в которых

используется LIKE:

 

 

 

АДРЕС LIKE ’% Беркли %’

будет

принимать

значение

 

истина, если АДРЕС содержит

 

где-либо

внутри него строку

 

’Беркли’

 

 

НОМЕР_ПОСТАВЩИКА LIKE ’S__’

будет

принимать

 

значение истина, если значение

 

в столбце НОМЕР_ПОСТАВ-

 

ЩИКА состоит в точности из

 

трех литер и первая из них

 

литера «S»

 

НАЗВАНИЕ LIKE ’% К___’

будет

принимать

значение

истина, если значение в столбце НАЗВАНИЕ состоит из четырех или более литер и трем последним из них предшествует литера

«К»

247

СОСТОЯНИЕ > 25 СОСТОЯНИЕ < = 25 СОСТОЯНИЕ = 25 СОСТОЯНИЕ !=25 СОСТОЯНИЕ =

ГОРОД NOT LIKE ’% Е %’

будет

принимать значение

 

истина, если значение ГОРОД

 

не содержит литеры «Е»

Выборка, при

которой

вовлекается null

(неопределенное значение)

Допустим, например, что значением в столбце СОСТОЯНИЕ для поставщика S5 является не 30, а неопределенное значение. Выдать номера поставщиков, у которых состояние больше, чем 25:

SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE СОСТОЯНИЕ > 25;

В результате получим:

НОМЕР_ПОСТАВЩИКА

S3

Здесь поставщик S5 не был назван в результате. Если неопределенное значение сравнивается с некоторым другим значением при вычислении предиката, то независимо от используемого оператора сравнения результатом сравнения никогда не является истина, даже если этот другой операнд также является неопределенным значением. Иными словами, если оказывается, что СОСТОЯНИЕ имеет неопределенное значение, то ни одно из следующих сравнений не будет принимать значение истина:

NULL (Это недопустимая синтаксическая конструкция. См. ниже)

СОСТОЯНИЕ != NULL (Это—тоже).

248

Поэтому если издать запрос:

SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE СОСТОЯНИЕ < = 25;

и сравнить его результат с результатом предыдущего запроса, то можно установить, что поставщик S5 не появляется ни в одном из них. Результат приведенного запроса:

НОМЕР_ПОСТАВЩИКА

S1

S2

S4

Для проверки наличия (или отсутствия) неопределенного значения предусмотрен специальный предикат вида:

имя — столбца IS [NOT] NULL

Например:

SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE СОСТОЯНИЕ IS NULL;

В результате имеем:

НОМЕР_ПОСТАВЩИКА

S5

Синтаксическая конструкция «СОСТОЯНИЕ = NULL» является некорректной, поскольку ничто — и даже само неопределенное значение — не считается равным неопределенному значению. (Несмотря на это, два неопределенных значения рассматриваются, однако, как дубликаты друг друга при исключении дубликатов.

249

Предложение SELECT DISTINCT (ВЫБРАТЬ РАЗЛИЧНЫЕ) даст в результате не более одного неопределенного значения. Аналогичным образом индекс со спецификацией UNIQUE (уникальный) будет допускать в индексируемом столбце не более одного неопределенного значения. Наконец, при упорядочении ORDER BY (УПОРЯДОЧИТЬ ПО) неопределенные значения интерпретируются, как будто бы они больше или равны всем значениям, не являющимся неопределенными).

Заметим, между прочим, что использование символа NULL во фразе SELECT не допускается. Например, следующая конструкция некорректна:

SELECT НОМЕР_ДЕТАЛИ, ’ВЕС = ’, NULL

FROM P

WHERE ВЕС IS NULL;

Запросы, использующие соединение

Способность «соединять» две или более таблицы в одну представляет собой одну из наиболее мощных возможностей реляционных систем. Фактически наличие операции соединения (join) — едва ли не самое главное, что отличает реляционные системы от систем других типов. Итак, что такое соединение? Говоря нестрого, это запрос, в котором выборка данных осуществляется более чем из одной таблицы. Ниже приводится простой пример.

Простое эквисоединение

Выдать все комбинации информации о таких поставщиках и деталях, которые размещены в одном и том же городе (иначе говоря, «соразмещены»—безобразный, но удобный термин):

SELECT S.*, P.*

FROM S, Р

WHERE S.ГОРОД = Р.ГОРОД;

250