Главная страница
Навигация по странице:

  • 5.2. Выборка без использования фразы WHERE

  • Здесь и далее мы будем иллюстрировать результаты выполнения предло- жений SQL на примерах работы с базой данных "COOK", содержимое

  • ), содержимое которой приведено на компакт-диске, прилагаемом к книге. Последнее будет каждый раз спе- циально оговариваться.

  • 5.2.2. Исключение дубликатов

  • 5.2.3. Выборка вычисляемых значений

  • 5.3. Выборка c использованием фразы WHERE

  • 5.3.1. Использование операторов сравнения

  • 5.3.2. Использование BETWEEN

  • Таблица 5.1. Минимальные оклады

  • 5.3.3. Использование IN

  • 5.3.4. Использование LIKE

  • 5.4. Выборка с упорядочением ( ORDER BY

  • 5.5. Агрегирование данных

  • 5.5.1 Агрегатные SQL - функции

  • 5.5.2. Функции без использования фразы GROUP BY

  • 5.5.3. Фраза GROUP BY

  • 5.5.4. Использование фразы HAVING

  • 5.6. Иерархические запросы

  • Кириллов В.В., Громов Г.Ю. - Введение в реляционные базы данных. Литература для вузов isbn 9785941577705 в книге рассматриваются основные понятия баз данных и систем управления ими


    Скачать 11.62 Mb.
    НазваниеЛитература для вузов isbn 9785941577705 в книге рассматриваются основные понятия баз данных и систем управления ими
    АнкорКириллов В.В., Громов Г.Ю. - Введение в реляционные базы данных.pdf
    Дата16.04.2018
    Размер11.62 Mb.
    Формат файлаpdf
    Имя файлаКириллов В.В., Громов Г.Ю. - Введение в реляционные базы данных.pdf
    ТипЛитература
    #18127
    страница8 из 28
    1   ...   4   5   6   7   8   9   10   11   ...   28
    Глава 5
    Запросы с использованием
    единственной таблицы
    5.1. О предложениях
    SELECT
    и
    SUBQUERY
    SELECT
    — предложение языка SQL извлекает строки, столбцы и производные значения (например, вычисляемые выражения) из одной или нескольких таб- лиц базы данных.
    В большинстве приложений
    SELECT
    является наиболее часто используемым оператором DML. При формировании запроса
    SELECT
    пользователь описыва- ет ожидаемый набор данных, но не указывает, какие физические операции должны быть произведены для получения этого набора. Определение для за- проса оптимального плана является задачей СУБД, а точнее — оптимизатора.
    Полный синтаксис стандартного предложения
    SELECT
    очень мощный и слож- ный, но его можно разделить на следующие основные фразы.
    SELECT [{ALL | DISTINCT}] отбираемый_элемент [AS псевдоним] [,...]
    FROМ [ONLY | OUTER]
    { имя_таблицы [[AS] псевдоним] |
    имя_представления [[AS] псевдоним] }[,...]
    [ [тип_соединения] JOIN условие_соединения ]
    [WHERE условие_поиска [ {AND | OR | NOT} условие_поиска [...]]
    [[ START WITH условие ]CONNECT BY [PRIOR] условие ]
    [GROUP BY группировка_по_выражению { группировка_по_столбцам |
    ROLLUP группировка_по_столбцам | CUBE группировка_по_столбцам |
    GROUPING SETS ( список_наборов_группировок ) | ( ) |
    набор_группировок, список__наборов_ группировок }
    [HAVING
    условие_поиска] ]
    [ORDER BY {выражение_для_сортировки [ASC | DESC]} [,...] ];

    Часть
    II.
    Язык SQL. Извлечение данных
    100
    Расшифровка сокращений
    отбираемый_элемент
    ,
    псевдоним
    ,
    имя_таблицы
    ,
    имя_представления
    ,
    условие_соединения
    ,
    условие_поиска
    и других, входя- щих в этот синтаксис, намного его усложнит. Еще более сложным и громозд- ким будет выглядеть синтаксис
    SELECT
    для Oracle Database 10g, в котором существует очень большое количество расширений стандарта SQL:2003 [6].
    Поэтому приведем здесь лишь краткое назначение основных фраз предложе- ния
    SELECT
    , перенеся их подробное изучение в следующие разделы данной главы и главы 6:

    FROM
    — содержит перечень таблиц, из которых должна выводиться запра- шиваемая информация;

    SELECT
    — содержит список столбцов из таблиц, перечисленных во фразе
    FROM
    , а также выражений, использующих значения из этих таблиц;

    WHERE
    — включает набор условий для отбора определенных строк таблиц, из которых должна выводиться запрашиваемая информация;

    CONNECT BY
    — определяет условие соотношения между родительскими стро- ками и их строками-потомками в иерархических запросах (см. разд. 5.6);

    GROUP BY
    — разбивает выводимые строки на логические группы, приме- няя к ним указанные в
    SELECT
    агрегатные функции (
    COUNT
    ,
    SUM
    ,
    MAX
    и др.), создавая для каждой из групп итоговую строку с количеством, суммой, максимумом и др. (см. разд. 4.6);

    HAVING
    — включает набор условий для отбора определенных итоговых строк из тех, которые получаются при выполнении фразы
    GROUP BY
    ;

    ORDER BY
    — сортирует полученный набор строк или итоговых строк.
    Напомним, что
    SELECT
    , как и любое другое предложение языка SQL, должно заканчиваться символом точка с запятой.
    Предложение
    SUBQUERY
    (подзапрос) — это предложение
    SELECT
    , заключенное в круглые скобки и встроенное в тело другого запроса. Подзапросы (вложен- ные запросы) позволяют получать одно или несколько значений и помещать их в предложения
    SELECT
    ,
    INSERN
    ,
    UPDATE
    или
    DELETE
    или в другой подзапрос.
    Подробно о них будет рассказано в главе 6.
    5.2. Выборка без использования фразы
    WHERE
    В этом разделе мы будем рассматривать простейшую форму предложения
    SELECT
    :
    SELECT ALL | DISTINCT}] отбираемый_элемент [[AS] псевдоним] [,...]
    FROМ имя_таблицы [[AS] псевдоним];

    Глава 5. Запросы с использованием единственной таблицы
    101
    Опишем кратко ключевые слова этого предложения.
    [{ALL | DISTINCT}] отбираемый_элемент
    Используется для описания результирующего набора значений, извлекаемых из базы данных при выполнении предложения
    SELECT
    Отбираемьй_элемент
    может представлять собой константу, агрегат или скаляр- ную функцию, математическое выражение, параметры или переменную или же подзапрос, но наиболее часто
    отбираемый_элемент
    —это столбец таб- лицы или представления. Несколько таких элементов должны разделяться запятыми.
    Если данные извлекаются из контекста, отличного от контекста текущего пользователя, перед столбцом нужно указывать префикс в виде схемы или имени владельца. Если таблица принадлежит другому пользователю, то в ссылке на столбец указывать имя этого пользователя. Чтобы извлечь все столбцы таблицы, указанной в предложении
    FROM
    , можно использовать крат- кое написание в виде звездочки (
    *
    ).
    Ключевое слово
    ALL
    , заданное по умолчанию, приводит к извлечению всех записей, удовлетворяющих критерию отбора. Ключевое же слово
    DISTINCT
    заставляет базу данных отфильтровывать все дублирующиеся записи и воз- вращать экземпляр из нескольких идентичных записей.
    AS псевдоним
    заменяет имя столбца более кратким именем. Это предложение особенно полезно для замены непонятных или длинных имен и выражений понятными обозначениями.
    FROM имя_таблицы [[AS] псевдоним]
    Это предложение служит для указания таблицы, из которой запрос получает данные. Предложение
    FROM
    такжепозволяет назначать псевдонимы длинным именам таблиц.
    Отметим, что псевдонимы в этой и предыдущей фразе действуют только в пре- делах одного запроса, а также, что слово
    [AS]
    можно опустить.
    Здесь и далее мы будем иллюстрировать результаты выполнения предло-
    жений SQL на примерах работы с базой данных "COOK", содержимое
    которой приведено в табл. 3.1—3.10 данной книги. Иногда (для более
    сложных примеров) мы воспользуемся достаточно содержательной ба-
    зой данных "UCHEB" (см. главу 19), содержимое которой приведено на
    компакт-диске, прилагаемом к книге. Последнее будет каждый раз спе-
    циально оговариваться.

    Часть
    II.
    Язык SQL. Извлечение данных
    102
    5.2.1. Простая выборка
    Сформулируем запрос на получения названия, статуса и месторасположения каждого из поставщиков:
    SELECT название, статус, город
    FROM поставщики;
    НАЗВАНИЕ СТАТУС ГОРОД
    -------- ---------- ---------
    СЫТНЫЙ рынок Ленинград
    ПОРТОС кооператив Резекне
    ШУШАРЫ совхоз Пушкин
    ТУЛЬСКИЙ универсам Ленинград
    УРОЖАЙ коопторг Луга
    ЛЕТО агрофирма Ленинград
    ОГУРЕЧИК ферма Паневежис
    КОРЮШКА кооператив Йыхви
    При необходимости получения полной информации о поставщиках, можно было бы дать запрос
    SELECT код_поставщика, название, статус, город, адрес, телефон
    FROM Поставщики; или более краткую нотацию, где вместо перечня всех имен таблицы
    Постав- щики используется рассмотренный в предыдущем разделе символ (
    *
    ):
    SELECT *
    FROM Поставщики;
    Результат любого из этих запросов имеет вид:
    КОД_ПОСТАВЩИКА НАЗВАНИЕ СТАТУС ГОРОД АДРЕС ТЕЛЕФОН
    -------------- -------- ---------- --------- -------------- -------
    1 СЫТНЫЙ рынок Ленинград Сытнинская,3 2329916 2 ПОРТОС кооператив Резекне Садовая,27 317664 3 ШУШАРЫ совхоз Пушкин Новая, 17 4705038 4 ТУЛЬСКИЙ универсам Ленинград Тульский,5 2710837 5 УРОЖАЙ коопторг Луга Песчаная,19 789000 6 ЛЕТО агрофирма Ленинград Пулковская,8 2939729 7 ОГУРЕЧИК ферма Паневежис Укмерге,15 127331 8 КОРЮШКА кооператив Йыхви Нарвское ш.,64 432123

    Глава 5. Запросы с использованием единственной таблицы
    103
    Еще один пример. Выдать основу всех блюд:
    SELECT Основа
    FROM Блюда; дает результат, в котором среди десяти первых значений всего лишь четыре уникальных: овощи, мясо, рыба и молоко.
    ОСНОВА
    ------
    Овощи
    Мясо
    Овощи
    Рыба
    Рыба
    Мясо
    Молоко
    Молоко
    Мясо
    Рыба
    5.2.2. Исключение дубликатов
    В предыдущем примере был выдан правильный, но не совсем удачный пере- чень основных продуктов: из него не были исключены дубликаты. Это мож- но сделать, дополнив запрос ключевым словом
    DISTINCT
    (различный, раз- личные), что позволит получить следующий результат:
    SELECT DISTINCT Основа
    FROM Блюда;
    ОСНОВА
    ------
    Кофе
    Крупа
    Молоко
    Мясо
    Овощи
    Рыба
    Фрукты
    Яйца
    Здесь всего восемь строк, в которых содержатся все уникальные значения столбца
    Основа таблицы
    Блюда

    Часть
    II.
    Язык SQL. Извлечение данных
    104
    5.2.3. Выборка вычисляемых значений
    Из описания синтаксиса предложения
    SELECT
    известно, что в нем может содер- жаться не только перечень столбцов таблицы или символ
    *
    , но и выражения.
    Например, если нужно получить значение калорийности всех продуктов, то можно учесть, что при окислении 1 г углеводов или белков в организме осво- бождается в среднем 4.1 ккал, а при окислении 1 г жиров — 9.3 ккал, и вы- дать запрос:
    SELECT Продукт, ((Белки + Углев)*4.1 + Жиры*9.3)
    FROM
    Продукты; позволяющий получить следующий результат:
    ПРОДУКТ (БЕЛКИ+УГЛЕВ)*4.1+ЖИРЫ*9.3
    -------- --------------------------
    Говядина 1928,1
    Судак 1523
    Масло 8287,5
    Майонез 6464,7
    Яйца 1618,9
    Сметана 3011,4
    Молоко 605,1
    Творог 1575
    Морковь 349,6
    Лук 459,2
    Помидоры 196,8
    Зелень 118,9
    Рис 3512,1
    Мука 3556,7
    Яблоки 479,7
    Сахар 4091,8
    Кофе 892,4
    Фраза
    SELECT
    может включать не только выражения для вычисления число- вых значений, но и текстовые выражения, а также числовые или текстовые константы.
    В качестве примера дополним предыдущий запрос константой 'Калорий ='
    , расположенной перед вычисляемым значением, и дадим псевдоним
    Калор выражению для вычисления калорийности продуктов:
    SELECT Продукт, 'Калорий =',
    ((Белки + Углев)*4.1 + Жиры *9.3) Калор
    FROM
    Продукты;

    Глава 5. Запросы с использованием единственной таблицы
    105
    Результат его выполнения будет иметь вид:
    ПРОДУКТ 'КАЛОРИЙ=' КАЛОР
    -------- ---------- ----------
    Говядина Калорий = 1928,1
    Судак Калорий = 1523
    Попробуем теперь создать текстовое выражение, воспользовавшись для этого оператором конкатенации (см. разд. 4.4.4). Создадим набор строк, каждая из которых содержит все данные о поставщике кроме его кода:
    SELECT статус||' '||название||' - адрес: '
    ||город||', '||адрес Поставщики
    FROM Поставщики;
    Результат выполнения такого запроса имеет вид:
    ПОСТАВЩИКИ
    ------------------------------------------------------ рынок СЫТНЫЙ - адрес: Ленинград, Сытнинская,3 кооператив ПОРТОС - адрес: Резекне, Садовая,27 совхоз ШУШАРЫ - адрес: Пушкин, Новая, 17 универсам ТУЛЬСКИЙ - адрес: Ленинград, Тульский,5 коопторг УРОЖАЙ - адрес: Луга, Песчаная,19 агрофирма ЛЕТО - адрес: Ленинград, Пулковская,8 ферма ОГУРЕЧИК - адрес: Паневежис, Укмерге,15 кооператив КОРЮШКА - адрес: Йыхви, Нарвское ш.,64
    Используя разнообразные функции работы со строками (см. разд. 4.6) можно существенно "разукрасить" этот результат. Воспользуемся только одной из них —
    RPAD
    , позволяющей дополнить строку справа до указанной длины пробелами (по умолчанию) или любым набором символов:
    SELECT RPAD(статус||' '||название,20)||' - адрес: '
    ||город||', '||адрес Поставщики
    FROM Поставщики;
    ПОСТАВЩИКИ
    ------------------------------------------------------- рынок СЫТНЫЙ - адрес: Ленинград, Сытнинская,3 кооператив ПОРТОС - адрес: Резекне, Садовая,27 совхоз ШУШАРЫ - адрес: Пушкин, Новая, 17 универсам ТУЛЬСКИЙ - адрес: Ленинград, Тульский,5 коопторг УРОЖАЙ - адрес: Луга, Песчаная,19

    Часть
    II.
    Язык SQL. Извлечение данных
    106
    агрофирма ЛЕТО - адрес: Ленинград, Пулковская,8 ферма ОГУРЕЧИК - адрес: Паневежис, Укмерге,15 кооператив КОРЮШКА - адрес: Йыхви, Нарвское ш.,64
    5.3. Выборка
    c
    использованием фразы
    WHERE
    Даже в такой микроскопической базе данных, какой является рассматривае- мая нами база данных "COOK", нас часто интересуют только определенные строки таблиц. Для этого в SQL существует фраза
    WHERE
    , позволяющая ука- зать критерии для отбора нужных строк.
    Синтаксис этой фразы имеет вид:
    WHERE условие_поиска [ {AND | OR | NOT} условие_поиска [...], где
    условие_поиска одна из следующих конструкций:

    значение { = | <> | < | <= | > | >= } { значение | (подзапрос) }

    значение_1 [NOT] BETWEEN значение_2 AND значение_3

    значение [NOT] IN { (константа [,константа]...) | (подзапрос) }

    значение IS [NOT] NULL

    [таблица.]столбец [NOT] LIKE 'строка_символов' [ESCAPE 'символ']

    EXISTS (подзапрос)
    Кроме традиционных операторов сравнения (
    = | <> | < | <= | > | >=
    ) в
    WHERE
    -фразе используются условия
    BETWEEN
    (между),
    LIKE
    (похоже на),
    IN
    (принадлежит),
    IS NULL
    (не определено) и
    EXISTS
    (существует), которые могут предваряться оператором
    NOT
    (не). Критерий отбора строк формируется из одного или нескольких условий, соединенных логическими операторами:

    AND
    — когда должны удовлетворяться оба разделяемых с помощью
    AND
    условия;

    OR
    — когда должно удовлетворяться одно из разделяемых с помощью
    OR
    условий;

    AND
    NOT
    — когда должно удовлетворяться первое условие и не должно второе;

    OR
    NOT
    — когда или должно удовлетворяться первое условие или не долж- но удовлетворяться второе.
    При этом существует приоритет
    AND
    над
    OR
    (сначала выполняются все опе- рации
    AND
    и только после этого операции
    OR
    ). Для получения желаемого

    Глава 5. Запросы с использованием единственной таблицы
    107
    результата
    WHERE
    -условия должны быть введены в правильном порядке, ко- торый можно организовать с помощью скобок.
    При обработке условия числа сравниваются алгебраически — отрицательные числа считаются меньшими, чем положительные, независимо от их абсолют- ной величины. Строки символов сравниваются в соответствии с их представ- лением в коде, используемом в конкретной СУБД, например, в коде ASCII.
    Если сравниваются две строки символов, имеющих разные длины, более ко- роткая строка дополняется справа пробелами для того, чтобы они имели оди- наковую длину перед осуществлением сравнения.
    В заключение отметим, что плохо написанная фраза
    WHERE
    может ухудшить производительность полезного во всех прочих отношениях предложения
    SELECT
    , поэтому деталями использования фразы
    WHERE
    необходимо владеть хорошо.
    5.3.1. Использование операторов сравнения
    В синтаксисе фразы
    WHERE
    показано, что для отбора нужных строк таблицы можно использовать операторы сравнения
    =
    (равно),
    <>
    (не равно),
    <
    (мень- ше),
    <=
    (меньше или равно),
    >
    (больше),
    >=
    (больше или равно), которые мо- гут предваряться оператором
    NOT
    , создавая, например, отношения "не меньше" и "не больше".
    Так, для получения перечня продуктов, практически не содержащих углево- дов, можно сформировать запрос
    SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
    FROM
    Продукты
    WHERE Углев = 0; и получить:
    ПРОДУКТ БЕЛКИ ЖИРЫ УГЛЕВ K CA NA B2 PP C
    -------- ------ ------ ------ ----- ----- ----- ------ ------ -----
    Говядина 189,0 124,0 0,0 3150 90 600 1,5 28,0 0
    Судак 190,0 80,0 0,0 1870 270 0 1,1 10,0 30
    Возможность использования нескольких условий, соединенных логическими операторами
    AND
    ,
    OR
    ,
    AND NOT и
    OR NOT
    , позволяет осуществить более де- тальный отбор строк. Так, для получения перечня продуктов, практически не содержащих углеводов и натрия, можно сформировать запрос:
    SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
    FROM
    Продукты
    WHERE Углев = 0 AND Na = 0;

    Часть
    II.
    Язык SQL. Извлечение данных
    108
    Результат запроса имеет вид:
    ПРОДУКТ БЕЛКИ ЖИРЫ УГЛЕВ K CA NA B2 PP C
    -------- ------ ------ ------ ----- ----- ----- ------ ------ -----
    Судак 190,0 80,0 0,0 1870 270 0 1,1 10,0 30
    Добавим к этому запросу еще одно условие:
    SELECT Продукт, Белки, Жиры, Углев, K, Ca, Na, B2, PP, C
    FROM
    Продукты
    WHERE Углев = 0 AND Na = 0 AND Продукт <> 'Судак'; и получим на экране сообщение "No rows exist or satisfy the specified clause" или "строки не выбраны" или просто заголовок без строк, в зависимости от вида и настройки того приложения, с помощью которого производится реа- лизация запроса.
    5.3.2. Использование
    BETWEEN
    С помощью
    BETWEEN ... AND ...
    (находится в интервале от ... до ...) можно отобрать строки, в которых значение какого-либо столбца находится в задан- ном диапазоне.
    Например, выдать перечень продуктов, в которых значение содержания бел- ка находится в диапазоне от 10 до 50:
    SELECT Продукт, Белки
    FROM
    Продукты
    WHERE Белки BETWEEN 10 AND 50;
    ПРОДУКТ БЕЛКИ
    -------- ------
    Майонез 31,0
    Сметана 26,0
    Молоко 28,0
    Морковь 13,0
    Лук 17,0
    Можно задать и
    NOT BETWEEN
    (не принадлежит диапазону), например:
    SELECT Продукт, Белки, Жиры
    FROM
    Продукты
    WHERE Белки NOT BETWEEN 10 AND 50
    AND
    Жиры > 100;

    Глава 5. Запросы с использованием единственной таблицы
    109
    ПРОДУКТ БЕЛКИ ЖИРЫ
    -------- ------ ------
    Говядина 189,0 124,0
    Масло 60,0 825,0
    Яйца 127,0 115,0
    BETWEEN
    особенно удобен при работе с данными, задаваемыми интервалами, начало и конец которых расположены в разных столбцах.
    Для примера воспользуемся таблицей "минимальных окладов" (табл. 5.1), ве- личина которых непосредственно связана с зарплатами сотрудников универси- тета и другими выплатами. В этой таблице для текущего значения минималь- ного оклада установлена запредельная дата окончания 9 сентября 9999 года.
    Таблица 5.1. Минимальные оклады
    Миноклад Начало
    Конец
    90 01.05.1997 31.03.1999 110 01.04.1999 31.12.2000 200 01.01.2001 30.06.2001 300 01.07.2001 30.11.2001 450 01.12.2001 30.09.2003 600 01.10.2003 31.12.2004 720 01.01.2005 31.08.2005 800 01.09.2005 30.04.2006 1100 01.05.2006 30.09.2006 1221 01.10.2006 09.09.9999
    Если, например, потребовалось узнать, какие изменения минимальных окла- дов производились в 2000/2001 учебном году, то можно выдать запрос:
    SELECT Начало, Миноклад
    FROM
    Миноклады
    WHERE Начало BETWEEN '1-9-2000' AND '31-8-2001'; и получить результат:
    НАЧАЛО МИНОКЛАД
    ----------- --------
    01.01.2001 200,00 01.07.2001 300,00

    Часть
    II.
    Язык SQL. Извлечение данных
    110
    Отметим, что при формировании запросов значения дат следует заключать в апострофы, чтобы СУБД не путала их с выражениями и не пыталась вычи- тать из 31 значение 8, а затем 2001.
    Для выявления всех значений минимальных окладов, которые существовали в 2000/2001 учебном году, можно сформировать запрос:
    SELECT *
    FROM
    Миноклады
    WHERE Начало BETWEEN '1-9-2000' AND '31-8-2001'
    OR
    Конец BETWEEN '1-9-2000' AND '31-8-2001' получив:
    МИНОКЛАД НАЧАЛО КОНЕЦ
    -------- ---------- ----------
    110,00 01.04.1999 31.12.2000 200,00 01.01.2001 30.06.2001 300,00 01.07.2001 30.11.2001
    Наконец, для определения минимального оклада на 15-5-2001 можно дать запрос:
    SELECT Миноклад
    FROM
    Миноклады
    WHERE '15-5-2001' BETWEEN Начало AND Конец; получив:
    МИНОКЛАД
    --------
    300,00
    5.3.3.
    Использование
    IN
    Выдать сведения о блюдах на основе яиц, крупы и овощей:
    SELECT *
    FROM
    Блюда
    WHERE Основа IN ('Яйца', 'Крупа', 'Овощи');
    Результат:
    КОД_БЛЮДА БЛЮДО КОД_ВИДА ОСНОВА ВЫХОД ТРУД
    --------- ---------------- -------- ------ ------ ----
    1 Салат летний 1 Овощи 200,0 3 3 Салат витаминный 1 Овощи 200,0 4 16 Драчена 3 Яйца 180,0 4

    Глава 5. Запросы с использованием единственной таблицы
    111
    17 Морковь с рисом 3 Овощи 260,0 3 19 Омлет с луком 3 Яйца 200,0 5 20 Каша рисовая 3 Крупа 210,0 4 21 Пудинг рисовый 3 Крупа 160,0 6 23 Помидоры с луком 3 Овощи 260,0 4
    Рассмотренная форма
    IN
    является в действительности просто краткой запи- сью последовательности отдельных сравнений, соединенных операторами
    OR
    Предыдущее предложение эквивалентно такому:
    SELECT *
    FROM
    Блюда
    WHERE Основа = 'Яйца' OR Основа = 'Крупа' OR Основа = 'Овощи';
    Можно задать и
    NOT IN
    (не принадлежит), также есть возможность использо- вания
    IN
    (
    NOT IN
    ) с подзапросом (см. главу 6).
    5.3.4.
    Использование
    LIKE
    Оператор
    LIKE
    позволяет указывать строковый шаблон для проверки на сов- падение в предложениях
    SELECT
    ,
    INSERT
    ,
    UPDATE
    и
    DELETE
    . Строковый шаблон может включать обобщающие символы. И в стандарте и в Oracle поддержи- ваются два обобщающих символа:

    символ
    _
    (подчеркивание) заменяет любой одиночный символ;

    символ
    %
    (процент) заменяет любую последовательность из
    N
    символов
    (где
    N
    может быть нулем).
    Существует также ключевое слово
    ESCAPE (отменяющая_посдедовательность)
    , позволяющее включать в шаблон символы, которые в обычных условиях ин- терпретировались бы как обобщающие символы. Любой обобщающий сим- вол, перед которым стоит
    отменяющая_посдедовательность
    , не считается обобщающим, а считается обычным символом.
    При организации проверки по строковым шаблонам во фразе
    LIKE
    следует помнить:

    значимыми являются все символы, включая пробелы перед строкой и по- сле нее;

    с помощью фразы
    LIKE
    можно сравнивать разные типы данных, но строки в них хранятся по-разному. Так, надо представлять различия между типа- ми данных
    CHAR
    ,
    VARCHAR
    и
    DATE
    (см. разд. 4.5);

    использование фразы
    LIKE
    может заставить пользователя СУБД отказать- ся от употребления индексов или применять альтернативные, менее опти- мальные индексы, чем в простой операции сравнения.

    Часть
    II.
    Язык SQL. Извлечение данных
    112
    Синтаксис фразы
    LIKE
    в Oracle имеет вид:
    WHERE выражение [NOT] {LIKE | LIKEC | LIKE2 | LIKE4 } строковый_шаблон [ESCAPE отменяющая_посдедовательность ] где
    LIKEC
    использует полный набор символов UNICODE,
    LIKE2
    использует набор символов UNICODE USC2, а
    LIKE4
    использует набор символов
    UNICODE USC4.
    Поскольку Oracle учитывает регистр, следует включать строковый_шаблон
    , выражение или и то и другое в функцию
    UPPER
    (изменение регистра строки на верхний). В этом случае вы всегда будете сравнивать то, что нужно.
    Перейдем к примерам. Выдать перечень салатов:
    SELECT Блюдо
    FROM
    Блюда
    WHERE Блюдо LIKE 'Салат%';
    Результат выборки имеет вид:
    БЛЮДО
    ----------------
    Салат летний
    Салат мясной
    Салат витаминный
    Салат рыбный
    В этом примере
    SELECT
    осуществляет выборку тех строк таблицы
    Блюда
    , для которых значение в столбце
    Блюдо начинается сочетанием "Салат" и содер- жит любую последовательность из нуля или более символов, следующих за этим сочетанием. Если бы среди блюд были "Луковый салат", "Фруктовый салат" и т. п., то они не были бы найдены. Для их отыскания надо изменить фразу
    WHERE
    :
    WHERE Блюдо LIKE '%салат%' или исключить возможные различия между малыми и большими буквами:
    WHERE UPPER (Блюдо) LIKE UPPER ('%Салат%')
    Это позволит отыскать все салаты.
    5.4. Выборка с упорядочением (
    ORDER BY)
    Синтаксис фразы упорядочения имеет вид:
    ORDER BY { выражение для сортировки [ASC | DESC ] } [,...]
    В выражении для сортировки указывается тот элемент запроса, который бу- дет определять порядок данных в результирующем наборе. Обычно это имена

    Глава 5. Запросы с использованием единственной таблицы
    113
    или псевдонимы столбцов. Указывается также, что выражение для сортиров- ки должно возвращаться в восходящем (
    ASC
    ) или нисходящем (
    DESC
    ) порядке.
    По умолчанию используется восходящий порядок: от ранней даты к поздней, от младшего числового значения к старшему, от текстового значения, начи- нающегося на символ с наименьшим кодом ASCII, к символу с наибольшим кодом ASCII (для русских букв от "А" до "Я" и от "а" до "я").
    Можно задавать несколько выражений для сортировки. При этом используется порядок сортировки от главного к второстепенному: сначала результирующий набор сортируется по первому из указанных столбцов, затем одинаковые зна- чения первого столбца сортируются по второму столбцу, одинаковые значе- ния второго столбца — по третьему столбцу и т. д.
    Индивидуальные параметры сортировки столбца (
    ASC
    /
    DESC
    ) не зависят от других столбцов фразы
    ORDER BY
    , т. е. можно отсортировать результирующий набор по одному столбцу по возрастанию, по следующему — по убыванию и т. п.
    Пустые значения (
    NULL
    ) при сортировке всегда оказываются рядом (т. е. счи- таются одинаковыми). В Oracle по умолчанию (
    ASC
    ) они собираются внизу.
    При помощи
    DESC
    можно переместить их вверх.
    Наконец, в Oracle поддерживается выведенная из стандарта сортировка по номеру порядковой позиции столбца (псевдонима, выражения или подзапро- са) в списке
    SELECT
    Перейдем к примерам.
    Выдать перечень продуктов, содержание в них основных веществ в порядке убывания содержания белка и возрастания их калорийности:
    SELECT продукт, белки, жиры, углев,
    (Белки + Углев)*4.1 + Жиры*9.3 Калорий
    FROM продукты
    ORDER BY Белки DESC, Калорий ASC;
    Результат выполнения этого запроса имеет вид:
    ПРОДУКТ БЕЛКИ ЖИРЫ УГЛЕВ КАЛОРИЙ
    -------- ------ ------ ------ ----------
    Судак 190,0 80,0 0,0 1523
    Говядина 189,0 124,0 0,0 1928,1
    Творог 167,0 90,0 13,0 1575
    Кофе 127,0 36,0 9,0 892,4
    Яйца 127,0 115,0 7,0 1618,9
    Мука 106,0 13,0 732,0 3556,7
    Рис 70,0 6,0 773,0 3512,1

    Часть
    II.
    Язык SQL. Извлечение данных
    114
    Масло 60,0 825,0 90,0 8287,5
    Майонез 31,0 670,0 26,0 6464,7
    Молоко 28,0 32,0 47,0 605,1
    Сметана 26,0 300,0 28,0 3011,4
    Лук 17,0 0,0 95,0 459,2
    Морковь 13,0 1,0 70,0 349,6
    Зелень 9,0 0,0 20,0 118,9
    Помидоры 6,0 0,0 42,0 196,8
    Яблоки 4,0 0,0 113,0 479,7
    Сахар 0,0 0,0 998,0 4091,8
    Для еще одного примера воспользуемся базой данных "UCHEB". Реализуем запрос
    SELECT ид, фамилия, имя, отчество, дата_рождения
    FROM н_люди
    WHERE фамилия = 'Громов'
    ORDER BY имя, отчество, дата_рождения DESC; в котором отыскиваются все люди с фамилией Громов, результат сортирует- ся по имени и отчеству, а при одинаковых значениях имени и отчества, по дате рождения (от более поздней к более ранней).
    ИД ФАМИЛИЯ ИМЯ ОТЧЕСТВО ДАТА_РОЖДЕНИЯ
    ------ -------- --------- ------------- -------------
    125518 Громов Александр Анатольевич 18.05.1960 123040 Громов Александр Вадимович 19.09.1958 102709 Громов Александр Викторович 23.12.1961 142506 Громов Александр Дмитриевич 15.04.1986 129531 Громов Александр Олегович 26.10.1985 117245 Громов Андрей Викторович 24.03.1981 133898 Громов Андрей Владимирович 25.09.1986 122012 Громов Андрей Геннадьевич 18.10.1984 143792 Громов Валерий Александрович 13.06.1988 119218 Громов Валерий Геннадьевич 02.07.1983 100061 Громов Геннадий Юрьевич 29.05.1962 132910 Громов Дмитрий Александрович 17.04.1987 145639 Громов Дмитрий Евгеньевич 24.12.1989 133899 Громов Дмитрий Сергеевич 17.06.1987 126697 Громов Илья Сергеевич 23.03.1984 122240 Громов Илья Сергеевич 01.01.1984 142202 Громов Роман Геннадьевич 02.12.1988

    Глава 5. Запросы с использованием единственной таблицы
    115
    5.5. Агрегирование данных
    Многие запросы к базе данных не нуждаются в той степени детализации, ко- торую обеспечивают ранее рассмотренные SQL-запросы. Например, во всех запросах, перечисленных далее, требуется узнать всего одно или несколько значений, которые подытоживают информацию, содержащуюся в базе данных.

    Сколько поставщиков поставляет морковь?

    Сколько людей заказало "Салат летний" на завтра?

    Какова средняя трудоемкость приготовления блюд, включенных в меню?

    Какова средняя стоимость заказанных блюд на каждом месте в столовой?

    Какова средняя стоимость всех заказанных блюд?

    Сколько строк в таблице
    Состав
    ?

    Какие фамилии чаще всего встречаются в таблице н_люди
    ?

    Сколько человек имеют имя Александр?

    Сколько неуспевающих студентов в каждой из групп?

    Сколько неуспевающих студентов на каждом факультете?

    Сколько неуспевающих студентов в университете?
    SQL-запросы такого типа можно создавать с помощью агрегатных функций и фраз
    GROUP BY
    и
    HAVING
    5.5.1 Агрегатные SQL
    -
    функции
    В SQL существует ряд специальных стандартных функций (агрегатных SQL- функций). Кроме специального случая
    COUNT(*)
    каждая из этих функций оперирует совокупностью значений столбца некоторой таблицы и создает единственное значение, определяемое так:

    COUNT
    — число значений в столбце;

    SUM
    — сумма значений в столбце;

    AVG
    — среднее значение в столбце;

    MIN
    — самое малое значение в столбце;

    MAX
    — самое большое значение в столбце.
    Для функций
    SUM
    и
    AVG
    рассматриваемый столбец должен содержать число- вые значения.

    Часть
    II.
    Язык SQL. Извлечение данных
    116
    Следует отметить, что здесь столбец — это столбец виртуальной таблицы, в которой могут содержаться данные не только из столбца базовой таблицы, но и данные, полученные путем функционального преобразования и (или) связывания символами арифметических операций значений из одного или нескольких столбцов. При этом выражение, определяющее столбец такой таблицы, может быть сколь угодно сложным, но не должно содержать агре- гатных SQL-функций (вложенность таких функций не допускается). Однако из агрегатных SQL-функций можно составлять любые выражения.
    Аргументу всех функций, кроме
    COUNT(*)
    , может предшествовать ключевое слово
    DISTINCT
    (различный), указывающее, что избыточные дублирующие значения должны быть исключены перед тем, как будет применяться функ- ция. Специальная же функция
    COUNT(*)
    служит для подсчета всех без исклю- чения строк в таблице (включая дубликаты).
    5.5.2. Функции без использования
    фразы
    GROUP BY
    Если не используется фраза
    GROUP BY
    , то в перечень отбираемых_элементов
    SELECT
    можно включать лишь агрегатные SQL-функции или выражения, со- держащие такие функции. Другими словами, нельзя иметь в списке столбцы, не являющиеся аргументами агрегатных SQL-функций.
    Например, выдать данные о массе лука (
    Код_продукта=10
    ), проданного по- ставщиками, и указать количество этих поставщиков:
    SELECT SUM(К_во), COUNT(К_во)
    FROM
    Поставки
    WHERE Код_продукта=10;
    Результат будет выглядеть так:
    SUM(К_ВО) COUNT(К_ВО)
    --------- -----------
    220 2
    Если бы для вывода в результат еще и номера продукта был сформирован запрос
    SELECT Код_продукта, SUM(К_во), COUNT(К_во)
    FROM
    Поставки
    WHERE Код_продукта=10; то было бы получено сообщение об ошибке (на Oracle — "ORA-00937: груп- повая функция не является одногруппной"). Это связано с тем, что агрегатная

    Глава 5. Запросы с использованием единственной таблицы
    117
    SQL-функция создает единственное значение из множества значений столбца- аргумента, а для "свободного" столбца должно быть выдано все множество его значений. Без специального указания (оно задается фразой
    GROUP BY
    )
    SQL не будет выяснять, одинаковы значения этого множества (как в данном примере, где
    Код_продукта=10
    ) или различны (как было бы при отсутствии фразы
    WHERE
    ). Поэтому подобный запрос отвергается системой.
    Правда, никто не запрещает дать запрос:
    SELECT 'Кол-во лука =', SUM(К_во), COUNT(К_во)
    FROM
    Поставки
    WHERE Код_продукта=10; и получить:
    'КОЛ-ВО ЛУКА=' SUM(К_ВО) COUNT(К_ВО)
    -------------- --------- -----------
    Кол-во лука = 220 2
    Однако если нам все же хочется увидеть в результате (а не только в тексте запроса) значение кода продукта, то можно дать такой "смешной" запрос:
    SELECT MAX(Код_продукта), SUM(К_во), COUNT(К_во)
    FROM
    Поставки
    WHERE Код_продукта=10; основанный на том, что при формировании списка вывода в него попадут строки с кодом продукта, разным 10, и, следовательно, максимальное (или минимальное) значение этого кода будет равно 10:
    MAX(КОД_ПРОДУКТА) SUM(К_ВО) COUNT(К_ВО)
    ----------------- ---------- -----------
    10 220 2
    Отметим также, что в столбце-аргументе перед применением любой функ- ции, кроме
    COUNT(*)
    , исключаются все неопределенные значения. Если ока- зывается, что аргумент — пустое множество, функция
    COUNT
    принимает зна- чение 0, а остальные —
    NULL
    Например, для получения суммы цен, средней цены, количества поставляе- мых продуктов и количества разных цен продуктов, проданных коопторгом
    УРОЖАЙ
    (
    Код_поставщика=5
    ), а также для получения количества продуктов, которые могут поставляться этим коопторгом, можно дать запрос:
    SELECT SUM(Цена), AVG(Цена), COUNT(Цена),
    COUNT(DISTINCT Цена), COUNT(*)
    FROM
    Поставки
    WHERE Код_поставщика=5;

    Часть
    II.
    Язык SQL. Извлечение данных
    118
    и получить:
    SUM(ЦЕНА) AVG(ЦЕНА) COUNT(ЦЕНА) COUNT(DISTINCTЦЕНА) COUNT(*)
    ---------- ---------- ----------- ------------------- ----------
    6,2 1,24 5 4 5
    То в другом примере, где надо узнать "Сколько поставлено судака и сколько поставщиков его поставляют?":
    SELECT SUM(К_во), COUNT(К_во)
    FROM
    Поставки
    WHERE Код_продукта=2; будет получен ответ:
    SUM(К_ВО) COUNT(К_ВО)
    --------- -----------
    0
    Так как ни один из поставщиков не поставляет судака, то в этом результате
    COUNT(К_ВО)
    оказалось равным нулю, а
    SUM(К_ВО)
    — неопределенному зна- чению (
    NULL
    ), которое ни в стандарте, ни в Oracle не имеет видимого изобра- жения.
    Наконец, попробуем получить сумму массы поставленного лука с его сред- ней ценой:
    SELECT (SUM(К_во) + AVG(Цена))
    FROM
    Поставки
    WHERE Код_продукта=10;
    Результат
    (SUM(К_ВО)+AVG(ЦЕНА))
    ---------------------
    220,6
    Система с легкостью складывает два запрошенных числовых значения ("са- поги с яичницей"), не задумываясь о несуразности такого действия. Об этом должен заботиться пользователь, формирующий запрос.
    В завершение данного раздела сформируем запрос на получение статисти- ческих данных о людях, хранящихся в таблице
    Н_ЛЮДИ
    базы данных "UCHEBA":
    SELECT COUNT(*) людей,
    COUNT(DISTINCT фамилия) фамилий,
    COUNT(DISTINCT имя) имен,
    COUNT(DISTINCT отчество) отчеств
    FROM н_люди;

    Глава 5. Запросы с использованием единственной таблицы
    119
    при выполнении которого будет строка
    ЛЮДЕЙ ФАМИЛИЙ ИМЕН ОТЧЕСТВ
    ----- ------- ---- -------
    30331 14524 868 1296 содержащая общее число людей, хранящихся в таблице, а также число раз- личных фамилий, имен и отчеств у этих людей.
    5.5.3. Фраза
    GROUP BY
    Мы показали, как можно вычислить массу определенного продукта, постав- ляемого поставщиками. Предположим, что теперь требуется вычислить об- щую массу каждого из продуктов, поставляемых в настоящее время постав- щиками. Это можно легко сделать с помощью предложения:
    SELECT Код_продукта, SUM(К_во)
    FROM
    Поставки
    GROUP BY Код_продукта;
    Его результат имеет вид:
    КОД_ПРОДУКТА SUM(К_ВО)
    ------------ ----------
    1 370 3 250 4 100 5 170 6 220 7 200 8 150 10 220 11 150 12 30 13 190 14 70 15 370 16 250 17 50
    Фраза
    GROUP BY
    (группировать по) инициирует перекомпоновку строк табли- цы по группам, каждая из которых имеет одинаковые значения в столбце, указанном в
    GROUP BY
    . В рассматриваемом примере строки таблицы
    Поставки группируются так, что в одной группе содержатся все строки для продукта

    Часть
    II.
    Язык SQL. Извлечение данных
    120
    с
    Код_продукта=1
    , в другой для продукта с
    Код_продукта=3
    (строки с
    Код_ продукта=2
    нет, так как судак не поставляется ни одним из поставщиков) и т. д. Затем к каждой группе применяется фраза
    SELECT
    . Каждое выражение в этой фразе должно принимать единственное значение для группы, т. е. оно может быть либо:

    значением столбца, указанного в
    GROUP
    BY
    ;

    арифметическим выражением, включающим это значение;

    константой;

    одной из SQL-функций, которая оперирует всеми значениями столбца в группе и сводит эти значения к единственному значению (например, к сумме, как в нашем запросе).
    Определим теперь среднюю стоимость одного килограмма каждого из про- дуктов, находящихся в таблице поставки, их количество и среднюю цену этих продуктов:
    SELECT Код_продукта, ROUND(SUM(цена*к_во)/SUM(К_во),2) Средняя, SUM(К_во)
    Всего, AVG(Цена)
    FROM Поставки
    GROUP BY Код_продукта;
    Результат имеет вид:
    КОД_ПРОДУКТА СРЕДНЯЯ ВСЕГО AVG(ЦЕНА)
    ------------ ---------- ---------- ----------
    1 3,71 370 3,9 3 4 250 4 4 2,52 100 2,52 5 1,88 170 1,9 6 2,71 220 2,9 7 0,4 200 0,4 8 1 150 1 10 0,58 220 0,6 11 1,17 150 1,25 12 2,67 30 2,75 13 0,95 190 1,04 14 0,5 70 0,5 15 1,73 370 1,75 16 0,95 250 0,97 17 4,5 50 4,5
    Для того чтобы средняя стоимость определялась с точностью до копеек, в запросе использовалась функция
    ROUND(n,[m])
    , в которой n
    — округляемое

    Глава 5. Запросы с использованием единственной таблицы
    121
    числовое значение, а m
    — число десятичных знаков после запятой (точнее см. в разд. 4.6).
    Обратите внимание, что ряд значений средней стоимости не совпадает со средней ценой!
    Отметим также, что фраза
    GROUP BY
    не предполагает
    ORDER BY
    (хотя в рас- смотренных ранее примерах результаты упорядочены). Чтобы гарантировать упорядочение по
    Код_продукта результата рассматриваемого примера, следу- ет дать запрос:
    SELECT код_продукта, SUM(цена*к_во)/SUM(к_во) Средняя, AVG(цена)
    FROM поставки
    GROUP BY код_продукта;
    ORDER BY Код_продукта;
    Наконец, отметим, что строки таблицы можно группировать по любой ком- бинации ее столбцов. Пример такой группировки будет рассмотрен в сле- дующем разделе.
    5.5.4. Использование фразы
    HAVING
    Фраза
    HAVING
    играет такую же роль для групп, что и фраза
    WHERE
    для строк: она используется для исключения групп точно так же, как
    WHERE
    использует- ся для исключения строк. Эта фраза включается в предложение лишь при наличии фразы
    GROUP BY
    , а выражение в
    HAVING
    должно принимать единст- венное значение для группы.
    Например, выдать количество людей с совпадающими фамилиями, именами и отчествами. В список включить только тех, которые имеют более трех "полных тезок".
    SELECT фамилия, имя, отчество, COUNT(*)
    FROM н_люди
    GROUP BY фамилия, имя, отчество
    HAVING COUNT(*) > 3
    ORDER BY фамилия, имя, отчество;
    Оказалось, что в таблице
    Н_ЛЮДИ
    базы данных "UCHEBA" имеется девять групп лиц, имеющих более трех "полных тезок", а Смирновых Андреев Сер- геевичей — аж восемь штук.
    ФАМИЛИЯ ИМЯ ОТЧЕСТВО COUNT(*)
    --------- --------- ------------- --------
    Иванов Дмитрий Николаевич 4
    Иванов Дмитрий Сергеевич 4

    Часть
    II.
    Язык SQL. Извлечение данных
    122
    Иванов Сергей Александрович 5
    Кузнецов Сергей Владимирович 4
    Кузнецова Мария Александровна 4
    Михайлов Андрей Александрович 5
    Смирнов Александр Сергеевич 8
    Смирнов Сергей Владимирович 4
    Федоров Алексей Владимирович 4
    В разд. 6.5 можно познакомиться с более содержательным примером исполь- зования этой фразы.
    5.6. Иерархические запросы
    Если информация в таблице представлена, например, в виде генеалогическо- го дерева (родственные связи в виде дерева, в котором у корня расположен родоначальник, а на ветвях дерева — различные линии его потомков), то хо- телось бы иметь возможность получать ее наглядное представление доста- точно простым способом.
    В синтаксисе предложения
    SELECT
    (см. разд. 5.1) существует фраза:
    [[ START WITH условие ]CONNECT BY [PRIOR] условие ] где
    START WITH
    задает строки, которые будут выполнять в результирующем наборе poль родительских (корневых). Условие в этой фразе не должно со- держать подзапросов. Если фраза
    START WITH
    не задана, то все строки будут корневыми.
    CONNECT BY
    определяет условие соотношения между родительскими строка- ми и их строками-потомками (дочерними строками). Условие в этой фразе не должно содержать подзапросов.
    PRIOR
    используется для указания родительских строк вместо строк-потомков.
    В иерархических запросах псевдостолбец
    LEVEL
    используется для указания корневой точки (1), точек-первичных потомков (2), точек-вторичных потом- ков (3) и т. д.
    В этих запросах нельзя использовать фразы
    ORDER BY
    и
    GROUP BY
    .Длясорти- ровки одноранговых потомков одной родительской таблицы можно исполь- зовать фразу
    ORDER SIBLINGS BY
    Для примера создадим иерархический запрос для таблицы
    Н_ОТДЕЛЫ
    , описан- ной в разд. 2.2 (см. табл. 2.1).
    SELECT RPAD(' ', (LEVEL-1)*4)||TO_CHAR(o.ид)||' '|| o.имя_в_имин_падеже Отделы

    Глава 5. Запросы с использованием единственной таблицы
    123
    FROM н_отделы o
    START WITH o.отд_ид IS NULL
    CONNECT BY PRIOR o.ид = o.отд_ид
    ORDER SIBLINGS BY o.ид;
    Результат этого запроса будет иметь вид:
    ОТДЕЛЫ
    -------------------------------------------------------------------------
    777 Санкт-Петербургский государственный университет информационных техно- логий, механики и оптики
    701 факультет оптико-информационных систем и технологий
    201 кафедра оптико-электронных приборов и систем
    215 кафедра экологического приборостроения и мониторинга
    304 кафедра прикладной и компьютерной оптики
    305 кафедра информ.-измерительн. cистем оптического приборостр-я
    307 кафедра оптических технологий
    308 кафедра компьютеризации и проектирования оптических приборов
    467 межкафедральная лаборатория компьютерной оптики ОФ
    512 кафедра системотехники оптических приб. и комплексов
    515 ВКЦГОИ
    601 деканат факультета оптико-информационных систем и технологий
    702 факультет инженерно-физический
    202 кафедра электроники
    203 кафедра лазерной техники и биомедицинской оптики
    205 кафедра компьютерной теплофизики и энергофизич. мониторинга
    207 кафедра физики и техники оптической связи
    211 кафедра твердотельной оптоэлектроники
    216 кафедра мощных технологических лазеров
    310 кафедра лазерных технологий и экологического приборостроения
    440 межкафедральный вычислительный класс ИФФ
    602 деканат инженерно-физического факультета
    703 факультет компьютерных технологий и управления
    101 кафедра систем управления и информатики
    102 кафедра вычислительной техники
    108 кафедра проектирования компьютерных систем
    109 кафедра информационно-навигационных систем
    111 кафедра информатики и прикладной математики
    116 кафедра безопасных информационных технологий
    208 кафедра электротехники и прецизионных эл/механических систем

    Часть
    II.
    Язык SQL. Извлечение данных
    124
    511 кафедра МПБЭВА
    603 деканат факультета компьютерных технологий и управления
    704 факультет естественнонаучный
    106 кафедра теоретической и прикладной механики
    209 кафедра высшей математики
    210 кафедра физики
    217 кафедра технологии профессионального обучения
    218 кафедра математического моделирования
    468 межкафедральный компьютерный класс ЕНФ
    604 деканат естественнонаучного факультета
    705 факультет точной механики и технологий
    103 кафедра измерительных технологий и компьютерной томографии

    1   ...   4   5   6   7   8   9   10   11   ...   28


    написать администратору сайта