Язык QBE (Query-by-example)
9.2.1 Запросы
Приведем пример запроса QBE (таблица 9.2) эквивалентного следующему SQL-запросу:
SELECT deptno FROM dept WHERE dname='SALES'
Можно несколько расширить список команд, но мы сделаем это позже. Что еще можно добавить во второй и последующих строках?
- Константы, например, запись текстовой константы "SALES" в столбце dname на предыдущем рисунке означает условие "dname = 'SALES'".
- Переменные. В отличие от констант в исходной версии QBE они обозначаются именами с подчеркиванием, например, SMITH или KING. В инструменте, с которым вы работаете, вместо подчеркивания имени его выделяют знаками подчеркивания перед именем и после него, например, _X_ это обозначение переменной X. При этом мы можем и не использовать имен образцов для задания переменных.
- Условия. Например, запись ">1000" в столбце sal таблицы emp означала бы условие "sal>1000". Условие "sal=1000" можно записать как "=1000" или как "1000".
Результат запроса заданного в таблице 9.2 приведен в листинге 9.1.
Строк найдено: 1 Запрос: SELECT el.deptno FROM dept el WHERE el.dname = 'SALES' deptno 30Пример 9.1. SQL-запроса эквивалентного запросу из таблицы 9.2
Выведем имена сотрудников, работающих в отделе 20 и получающих больше 2900. Запрос выглядит так — таблица 9.3.
Запрос | ||||
---|---|---|---|---|
emp | ename | sal | mgr | deptno |
P. | >2900 | 20 | ||
Результат | ||||
Строк найдено: 3 Запрос: |
||||
SELECT el.ename FROM emp el WHERE e1.deptno=20 AND e1.sal>2900 |
||||
ename JONES SCOTT FORD |
Обратите внимание на то, что в SQL псевдонимы автоматически проставляются для всех таблиц, используемых в запросе. Это особенность инструмента, но не QBE.
Для упорядочения вывода по возрастанию используется команда "АО.", а для вывода по убыванию "DO.". Это аналоги слов Ascending и Descending из фразы ORDER BY в SQL.
Упоминавшееся при изучении исчисления на доменах условие принадлежности доменного значения кортежу обозначается пользователем за счет помещения значений столбцов в схему таблицы, что учитывает транслятор.
Основное назначение переменных — создание соединений таблиц. С этой целью под списком имен таблиц можно поместить две или более строк, заполненных командами и условиями. Соединение организуется по двум столбцам одной или разных таблиц, в которых проставлены переменные с одинаковыми именами. Рассмотрим пример.
Реализуем соединение таблицы emp с собой и с таблицей dept в запросе: "Найти имена и зарплаты служащих, получающих больше, чем JAMES, и работающих в отделе продаж (SALES)" — рисунок 9.3, таблица 9.4.
Результат | ||
---|---|---|
Строк найдено: 5 Запрос: |
||
SELECT e1.ename,e1.sal FROM emp e1,emp e2,dept e3 WHERE e1.sal>e2.sal AND e1.deptno=e3.deptno AND e2.dname='SALES' AND e2.ename='JAMES' |
||
ename ALLEN WARD MARTIN BLAKE TURNER |
sal 1600 1250 1250 2850 1500 |
Читаем первую строку команд и условий для emp: "Выбрать значения столбцов ename и sal из таблицы emp. Значение в столбце sal использовать для организации соединения. Значение в столбце deptno использовать в другом соединении". Из сравнения с текстом SQL-запроса видно, что первой строке запроса QBE соответствует первый экземпляр таблицы emp с псевдонимом el. Во второй строке для emp указано, что необходимо выбрать из emp строку для Джеймса и оставить в первом результате только строки, в которых значение зарплаты SALES больше, чем у Джеймса. Эта строка запроса QBE соответствует псевдониму e2 запроса SQL. И, наконец, в условии для dept устанавливается, что выбирается только строка отдела продаж. Устанавливается соединение со строками, выбранными из emp, у которых значение в столбце deptno такое же, как в отделе продаж. Для записи соединения использована переменная _SALES_. В запросе SQL этой последней строке соответствует псевдоним e3.
Кстати, порядок записи двух или более строк с командами и условиями для одной таблицы значения не имеет. Это позволяет пользователю вводить текст в том порядке, как он обдумывается. Эквивалентный запрос на языке SQL, соответствующий исходному заданию:
SELECT el.ename, el.sal FROM emp el, emp e2, dept e3 WHERE e1.sal> e2.sal AND — соединения e1 и e2 e1.deptno=e3.deptno AND — соединение e1 и e3 e3.dname='SALES' AND — условие для e3 e2.ename='JAMES' — условие для e2