Язык QBE (Query-by-example)
При необходимости распечатки отладочных данных достаточно проставить в нужной строке команды печати и прогнать на исполнение полученную версию.
В записи условия выбора можно работать с текстовыми шаблонами. Для этого часть литерала выделяют знаками подчеркивания в начале, середине или конце слова или предложения. В примере, приведенном ниже, запись A_LLEN_ в столбце ename означает, что ищутся значения, начинающиеся с "A", а _LLEN_ — это переменная с именем LLEN, включающая остальную часть слова. Шаблон _X_PA_Y_, означает слово или предложение, такие, что где-то в них содержатся последовательность букв "PA". Итак, наличие шаблона эквивалентно оператору LIKE в SQL. Это хорошо видно по следующему примеру в таблице 9.5
Запрос | ||||
---|---|---|---|---|
emp | ename | sal | deptno | |
P.A_LLEN_ | 30 | |||
Результат | ||||
Строк найдено: 2 Запрос: |
||||
SELECT e1.ename,e1.deptno FROM emp el WHERE el.ename LIKE 'A%' |
||||
ename ALLEN ADAMS |
deptno 30 20 |
Заметим, что переменные можно поместить в задании запроса в любых столбцах, как пустых, так и содержащих команды. В некоторых реализациях добавление переменной после команды P. обеспечивает вывод всех дублирующих значений, а переменные в столбцах без команды P. запрещают удаление соответствующих колонок в ответе.
Можно использовать отрицание запроса —. У нас отрицание обозначено "~". В следующем примере (таблица 9.6) требуется вывести имена всех сотрудников, не работающих в отделе продаж. Этот же запрос можно переписать с отрицанием условия — таблица 9.7.
emp | ename | sal | deptno |
---|---|---|---|
P. | _DNO_ | ||
dept | deptno | dname | loc |
_DNO_ | !=SALES |
Для того, чтобы в таблице-результате можно было иметь в заголовке имена столбцов, отличные от имен в исходных таблицах, в некоторых реализациях QBE создают шаблон результата, записывая в него нужные имена и связывая его с исходной таблицей или с соединением исходных таблиц.
Порядок таблиц и в этом случае несущественен. Объединение условий связками И и ИЛИ осуществляется за счет манипулирования переменными. Пример на применение связки И (таблица 9.8). Вывести имена сотрудников отдела 30 с зарплатой больше 1500, но меньше 3500.
Запрос | ||||||||
---|---|---|---|---|---|---|---|---|
emp | ename | mgr | sal | deptno | ||||
P._Name_ | P.>1500 | P. | ||||||
_Name_ | <3500 | |||||||
_Name_ | 30 | |||||||
Результат | ||||||||
Строк найдено: 2 Запрос: |
||||||||
SELECT el.ename, el.sal, el.deptno FROM emp el, emp e2, emp e3 WHERE e1.ename=e2.ename AND e1.ename=e3.ename AND e1.sal>1500 AND e2.sal<3500 AND e3.deptno=30 |
||||||||
ename ALLEN BLAKE |
sal 1600 2850 |
deptno30 30 |
Обратите внимание на то, что при реализации логической связки И во всех трех строках использовано одно имя переменной _Name_ в одном и том же столбце. Отметим, что условие "=30" можно было перенести в первую строку сократив, тем самым, запрос. Использование разных переменных позволяет включить связку ИЛИ. В качестве примера, выведем имена сотрудников, зарплата которых составляет $10000, $13000 или $16000 (таблица 9.9).
В блоке условий составляющие условия объединяют знаками & (И) и |
(ИЛИ).
Для указания столбца, по которому производят группирование в исходном варианте QBE, его подчеркивают двойной чертой. В нашей программе для указания на группирование использована функция G. (таблица 9.10).
В QBE используются многострочные функции аналоги функций SQL и оператор ALL. Это CNT. (аналог COUNT), SUM., AVG., MIN., MAX., а также UN. (уникальный). Функция UN. может быть присоединена к CNT., SUM. или AVG.. Например, CNT. UN. означает подсчет только различающихся значений.
Пример: найти суммы зарплат по всем отделам.
В QBE можно организовывать некоторые запросы в логике второго порядка. Как вы помните, в ней кванторы можно навешивать не только на переменные, но еще и на имена предикатов. А именам предикатов в реализациях реляционных баз соответствуют имена таблиц. В таких запросах можно, например, искать таблицу, в которой имеется какой-нибудь столбец, или искать таблицу, в одном из столбцов которой записан некто по фамилии SMITH и т.п.
Пример запроса в логике предикатов 2-го порядка: Выбрать все имена таблиц схемы:
P._TAB_
Переменная _TAB_ здесь заведомо может быть опущена. Если мы хотим организовать выдачу имен всех столбцов всех таблиц схемы, то команда должна быть записана так: P._TAB_P.. или P. P.:
P. P.
Легкость перехода к запросам в логике второго порядка можно для себя прояснить тем, что имя таблицы есть всего лишь первый элемент списка <имя_таблицы, имя_столбца+>, так что домен первой колонки как раз содержит имена таблиц, и нет принципиальной разницы с последующими столбцами. Знак "+" здесь означает, что имя_столбца может быть повторено один или большее число раз.
Заметим, что в реализациях QBE возможность запросов в логике второго порядка может отсутствовать. В SQL такие запросы можно организовать, используя таблицы или представления словаря.
Выборка с использованием блока условий
В Query-by-Example существует два двухмерных объекта. Один из них — шаблон таблицы — уже описан. Другой — это блок условий, имеющий всегда заголовок CONDITIONS. Пустой блок условий может быть выведен в любое время. Он позволяет задать одно или несколько условий, которые трудно выразить в шаблонах таблиц.
Пример (таблица 9.11): Вывести имена и зарплаты сотрудников, зарплата которых больше суммы зарплат Джонса и Аллена. Естественно, это простое условие могло быть выражено заменой в первой строке таблицы emp в столбце sal переменной _S1_ на условие ">(_S2_+_S3_)". Внесение сложных формул непосредственно в форму для таблицы, как минимум, неудобно.