Глава 2. Запросы с использованием единственной таблицы
2.1 О предложении SELECT
2.2 Выборка без использования фразы WHERE
2.3 Выборка c использованием фразы WHERE
2.4 Выборка с упорядочением
2.5 Агрегирование данных
В синтаксисе фразы WHERE (п.2.1) показано, что для отбора нужных строк таблицы можно использовать операторы сравнения = (равно), <> (не равно), < (меньше), <= (меньше или равно), > (больше), >= (больше или равно), которые могут предваряться оператором NOT, создавая, например, отношения "не меньше" и "не больше".
Так, для получения перечня продуктов, практически не содержащих углеводов, можно сформировать запрос
SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
FROM Продукты
WHERE Углев = 0;
|
и получить:
Продукт |
Белки |
Жиры |
Углев |
K |
Ca |
Na |
B2 |
PP |
C |
Говядина |
189. |
124. |
0. |
3150 |
90 |
600 |
1.5 |
28. |
0 |
Судак |
190. |
80. |
0. |
1870 |
270 |
0 |
1.1 |
10. |
30 |
Возможность использования нескольких условий, соединенных логическими операторами AND, OR, AND NOT и OR NOT, позволяет осуществить более детальный отбор строк. Так, для получения перечня продуктов, практически не содержащих углеводов и натрия, можно сформировать запрос:
SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
FROM Продукты
WHERE Углев = 0 AND Na = 0;
|
Результат запроса имеет вид
Продукт |
Белки |
Жиры |
Углев |
K |
Ca |
Na |
B2 |
PP |
C |
Судак |
190. |
80. |
0. |
1870 |
270 |
0 |
1.1 |
10. |
30 |
Добавим к этому запросу еще одно условие
SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
FROM Продукты
WHERE Углев = 0 AND Na = 0 AND Продукт <> 'Судак'
|
и получим на экране сообщение "No rows exist or satisfy the specified clause" или аналогичное (в зависимости от вкусов разработчиков разных СУБД), информирующее об отсутствии строк, удовлетворяющих заданному(ым) условию(ям).
С помощью BETWEEN ... AND ... (находится в интервале от ... до ...) можно отобрать строки, в которых значение какого-либо столбца находятся в заданном диапазоне.
Например, выдать перечень продуктов, в которых значение содержания белка находится в диапазоне от 10 до 50:
SELECT Продукт, Белки
FROM Продукты
WHERE Белки BETWEEN 10 AND 50;
|
Результат:
Продукт |
Белки |
Майонез |
31. |
Сметана |
26. |
Молоко |
28. |
Морковь |
13. |
Лук |
17. |
Можно задать и NOT BETWEEN (не принадлежит диапазону между), например:
SELECT Продукт, Белки, Жиры
FROM Продукты
WHERE Белки NOT BETWEEN 10 AND 50
AND Жиры > 100;
|
Результат:
Продукт |
Белки |
Жиры |
Говядина |
189. |
124. |
Масло |
60. |
825. |
Яйца |
127. |
115. |
BETWEEN особенно удобен при работе с данными, задаваемыми интервалами, начало и конец которых расположен в разных столбцах.
Для примера воспользуемся таблицей "минимальных окладов" (табл. 2.1), величина которых непосредственно связана со студенческой стипендией. В этой таблице для текущего значения минимального оклада установлена запредельная дата окончания 9 сентября 9999 года.
Таблица 2.1. Минимальные оклады.
Миноклад |
Начало |
Конец |
2250 |
01-01-1993 |
31-03-1993 |
4275 |
01-04-1993 |
30-06-1993 |
7740 |
01-07-1993 |
30-11-1993 |
14620 |
01-12-1993 |
30-06-1994 |
20500 |
01-07-1994 |
09-09-9999 |
Если, например, потребовалось узнать, какие изменения минимальных окладов производились в 1993/94 учебном году, то можно выдать запрос
SELECT Начало, Миноклад
FROM Миноклады
WHERE Начало BETWEEN '1-9-1993' AND '31-8-1994'
|
и получить результат:
Начало |
Миноклад |
01-12-1993 |
14620 |
01-07-1994 |
20500 |
Отметим, что при формировании запросов значения дат следует заключать в апострофы, чтобы СУБД не путала их с выражениями и не пыталась вычитать из 31 значение 8, а затем 1994.
Для выявления всех значений минимальных окладов, которые существовали в 1993/94 учебном году, можно сформировать запрос
SELECT *
FROM Миноклады
WHERE Начало BETWEEN '1-9-1993' AND '31-8-1994'
OR Конец BETWEEN '1-9-1993' AND '31-8-1994'
|
Миноклад |
Начало |
Конец |
7740 |
01/07/1993 |
30/11/1993 |
14620 |
01/12/1993 |
30/06/1994 |
20500 |
01/07/1994 |
09/09/9999 |
Наконец, для получения минимального оклада на 15-5-1994:
SELECT Миноклад
FROM Миноклады
WHERE '15-05-1994' BETWEEN Начало AND Конец
|
Результат:
Выдать сведения о блюдах на основе яиц, крупы и овощей
SELECT *
FROM Блюда
WHERE Основа IN (Яйца Крупа Овощи);
|
Результат:
БЛ |
Блюдо |
В |
Основа |
Выход |
Труд |
1 |
Салат летний |
З |
Овощи |
200. |
3 |
3 |
Салат витаминный |
З |
Овощи |
200. |
4 |
16 |
Драчена |
Г |
Яйца |
180. |
4 |
17 |
Морковь с рисом |
Г |
Овощи |
260. |
3 |
19 |
Омлет с луком |
Г |
Яйца |
200. |
5 |
20 |
Каша рисовая |
Г |
Крупа |
210. |
4 |
21 |
Пудинг рисовый |
Г |
Крупа |
160. |
6 |
23 |
Помидоры с луком |
Г |
Овощи |
260. |
4 |
Рассмотренная форма IN является в действительности просто краткой записью последовательности отдельных сравнений, соединенных операторами OR. Предыдущее предложение эквивалентно такому:
SELECT *
FROM Блюда
WHERE Основа=Яйца OR Основа=Крупа OR Основа=Овощи;
|
Выдать перечень салатов
SELECT Блюдо
FROM Блюда
WHERE Блюдо LIKE 'Салат%';
|
Результат:
Блюдо |
Салат летний |
Салат мясной |
Салат витаминный |
Салат рыбный |
Обычная форма "имя_столбца LIKE текстовая_константа" для столбца текстового типа позволяет отыскать все значения указанного столбца, соответствующие образцу, заданному "текстовой_константой". Символы этой константы интерпретируются следующим образом:
- символ _ (подчеркивание) – заменяет любой одиночный символ,
- символ % (процент) – заменяет любую последовательность из N символов (где N может быть нулем),
- все другие символы означают просто сами себя.
Следовательно, в приведенном примере SELECT будет осуществлять выборку записей из таблицы Блюда, для которых значение в столбце Блюдо начинается сочетанием 'Салат' и содержит любую последовательность из нуля или более символов, следующих за сочетанием 'Салат'. Если бы среди блюд были "Луковый салат", "Фруктовый салат" и т.п., то они не были бы найдены. Для их отыскания надо изменить фразу WHERE:
WHERE Блюдо LIKE '%салат%'
|
или при отсутствии различий между малыми и большими буквами (такую настройку допускают некоторые СУБД):
WHERE Блюдо LIKE '%Салат%'
|
Это позволит отыскать все салаты.
Как было рассказано в п.2.2.3, если при загрузке данных не введено значение в какое-либо поле таблицы, то СУБД поместит в него NULL-значение. Аналогичное значение можно ввести в поле таблицы, выполняя операцию изменения данных. Так, при отсутствии сведений о наличии у поставщиков судака и моркови в столбцы Цена и К_во соответствующих строк таблицы Поставки вводится NULL и там будет храниться код NULL-значения, а не 0, 0. или пробел. (Отметим, что в распечатке таблицы Поставки рис.1.1 в этих местах расположен пробел, установленный в СУБД для представления NULL-значения при выводе на печать).
В этом случае для выявления названий продуктов, отсутствующих в кладовой, шеф-повар может дать запрос
SELECT DISTINCT ПР
FROM Наличие
WHERE К_во IS NULL;
|
Результат:
Естественно, что для выявления продуктов, существующих в кладовой, следует дать запрос
SELECT DISTINCT ПР
FROM Наличие
WHERE К_во IS NOT NULL;
|
Использование условий
столбец IS NULL и столбец IS NOT NULL
|
вместо, например,
столбец = NULL и столбец <> NULL
|
связано с тем, что ничто - и даже само NULL-значение - не считается равным другому NULL-значению. (Несмотря на это, два неопределенных значения рассматриваются, однако, как дубликаты друг друга при исключении дубликатов, и предложение SELECT DISTINCT даст в результате не более одного NULL-значения.)
|