В лекции № 7 "Введение в Oracle SQL" в подразделе "Несамостоятельность группировки с обобщениями ROLLUP, CUBE и GROUPING SETS" представленная таблица сравнения содержит ошибки - окончания запросов пропущены. Видимо, ошибки вызваны некорректным переносом материала лекции. |
Лекция 5: Выборка данных. Общее построение предложения SELECT и фразы FROM и WHERE
Выборка данных
Бескозырка белая, в полоску воротник...
Пионеры смелые спросили напрямик:
"С какого, парень, года, с какого парохода
И на каких морях ты побывал, моряк?"
Фразы предложения SELECT
Предложение SELECT в SQL складывается из фрагментов, которые по примеру лингвистики носят название фраз (clauses). Иногда их удобно называть более общим словом "конструкции" или же словами "часть предложения".
Допустимые в предложении SQL фразы — это: SELECT, FROM, WHERE, GROUP BY, HAVING, CONNECT BY, ORDER BY, PIVOT/UNPIVOT. Общие правила использования фраз в предложении SELECT следующие:
- В каждом предложении обязаны быть фразы SELECT и FROM. Остальные фразы необязательны.
- Порядок следования фраз во всех предложениях фиксирован (например, GROUP BY всегда следует за WHERE и FROM, а ORDER BY всегда стоит в конце).
- Фраза HAVING может употребляться только в дополнении ко GROUP BY.
Начиная с версии 10 в Oracle SQL возможно еще употребление фразы MODEL, которая, однако, стоит особняком от прочих в силу своей синтаксической инородности и нетрадиционности для SQL. Сфера ее применения также специфична — это базы типа "склады данных", data warehouse. Ниже она не рассматривается.
Кроме этого может иметься фраза WITH, которую можно рассматривать как оформительскую (с версии 9) и процедурную (с версии 11.2) надстройку над "традиционным" предложением SELECT. Она рассматривается в соответствующем разделе ниже.
Логический порядок обработки предложения SELECT
Порядок обработки предложения SELECT также фиксирован и почти совпадает с порядком написания фраз в тексте. Исключения составляет (а) фраза SELECT, которая в отличие от написания обрабатывается в последнюю очередь, и (б) фразы CONNECT BY и WHERE, которые обрабатываются в порядке, обратном написанию:
[11-) с версии 11
Указанный порядок — логический. Это значит, что технические планы обработки запросов СУБД может предлагать самые разнообразные, и вовсе не обязательно они будут точно воспроизводить приведенную выше последовательность в каждом отдельном случае. Причина — в чудовищной затратности, которой чревато простое следование вышеприведенной схеме. Однако действие любого плана, фактически предлагаемого Oracle, никогда не будет вступать в противоречие с этой логикой обработки. Иными словами, когда программисту требуется понять, каким может оказаться результат запроса, он вполне вправе положиться на эту общую логическую последовательность обработки и не вдаваться в подробности фактического плана выполнения.
Она основывается на чередовании этапов вычисления (очередная фраза), так что каждый этап принимает какое-то множество данных на входе и вырабатывает множество данных на выходе. За исключением двух крайних случаев: множества данных на входе фразы FROM и окончательного результата на выходе фразы SELECT, — такие множества можно назвать промежуточными результатами вычислений в предложении SELECT. Вот как выглядит логическая схема обработки предложения SELECT, пожалуй самого распространенного вида SELECT … FROM a, b WHERE условие:
В частности, эта схема способна показать, что порядок указания источников данных во фразе FROM никак не сказывается на результате.
Далее приводятся два примера предсказания ответа путем применения техники последовательности промежуточных вычислений.
Пример 1 предложения SELECT
"Выдать в порядке приема на работу всех продавцов с их окладами":
SELECT ename, sal FROM emp WHERE job = 'SALESMAN' ORDER BY hiredate
(Здесь предполагается, что данные о всех сотрудниках исчерпываются таблицей EMP. В базе, отличной от схемы SCOTT, где не соблюдена ортогонализация данных, это может оказаться и не так).
Промежуточный результат после фраз FROM и WHERE
В силу того что источник данных для запроса в данном случае один, фраза FROM фактически ничего не вычисляет, а просто "берет" данные таблицы EMP из базы. Реальную работу — отсев строк согласно условию — выполняет фраза WHERE:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ------- ---------- --------- --------- --------- --------- --------- --------- 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
Промежуточный результат после фразы ORDER BY
На множестве строк, полученных от WHERE, фраза ORDER BY наводит порядок:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ------- ---------- --------- --------- --------- --------- --------- --------- 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30