- •2 Order by deptno;
- •3 Order by deptno;
- •10 Clark 2450
- •20 Smith 800
- •8 Row selected
- •11/05/2003 Main report Page: 1
- •Функции pl/sql
- •Insert into purchase values (‘Prod_1’, 10, sysdate, ’sh’);
- •Insert into purchase values (‘Prod_1’ ,10, sysdate-7,’sh’);
- •Iniтсaр(product_name)
- •2 Last_name,
- •20,’Dallas’,
- •30,’Chicago’,
- •40,’Boston’,
- •6 Rows selected.
- •Настройка среды sql*Plus
- •Файлы сценариев sql (скрипты)
- •Разновидности комментариев
- •16 Row selected
- •2 From emp, salgrade
- •4 And sal between losal and hisal;
- •Intersect
- •Union union at all
- •2 Union
- •4 Union
- •6 Minus
- •8 Order by 2,1;
- •Контрольные вопросы
16 Row selected
SQL>
Тот же запрос в синтаксисе ANSIявляется правым внешним соединением
SELECT ename, dname
FROM emp RIGHT OUTER JOINdept
ONemp.deptno = dept.deptno;
Тот же пример с левым внешним соединением:
SELECT ename, dname
FROM dept, emp
WHERE dept.deptno = emp.deptno(+);
А в стандарте ANSI:
SELECT ename, dname
FROM dept LEFT OUTER JOINemp
ON dept.deptno = emp.deptno;
Пример самосоединения. Здесь в таблицеempесть два поля с идентификаторами служащихempno(номер работника) иmgr(номер руководителя). Выводим список работников с именами их руководителей.
SELECT employee.ename, employee.job, mngr.ename
FROM emp employee, emp mngr
WHERE employee.mgr = mngr.empno(+);
Соединение может быть не только по равенству. Пример – по интервалу.
SQL> SELECT * FROM salgrade;
GRADE LOSAL HISAL
------- ------ ------
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
5 3001 9999
SQL> SELECT ename, job, sal
2 From emp, salgrade
3 WHERE grade = 4
4 And sal between losal and hisal;
ENAME JOB SAL
------- -------- --------
JONES MANAGER 2975
BLAKE MANAGER 2050
CLARK MANAGER 2450
SCOTT MANAGER 3000
FORD MANAGER 3000
SQL>
Соединение – лишь один из методов слияния результирующих наборов нескольких запросов в один результирующий набор.
Операторы соединения
Оператор |
Получаемые результаты |
UNION |
Все строки обоих операторов SELECT; повторяющиеся значения удаляются |
UNION ALL |
Все строки обоих операторов SELECT; повторяющиеся значения показываются |
INTERSECT |
Строки, которые возвращены и первым и вторым оператором SELECT |
MINUS |
Строки, которые возвращены первым оператором SELECT, исключая те, которые возвращены вторым оператором (в стандартеSQLэтот оператор обозначенEXCEPT) |
Схема работы операторов соединения
MINUS
Данные, полученные первым оператором
SELECT
Данные, полученные вторым оператором
SELECTIntersect
Union union at all
Пример. Пусть из таблицы empсозданы три таблицы (для каждого отдела своя) по следующему принципу:
CREATE TABLE dept10 (ename1, job, sal1) AS
SELECT ename, job, sal
FROM emp
WHERE deptno = 10;
Тогда, по следующему запросу, можно получить информацию одновременно из трёх таблиц, причём исключить из неё строку на основе информации из четвертой таблицы (emp).
SQL> SELECT ename1, sal FROM dept10 WHERE sal > 2500
2 Union
3 SELECT ename2, sal FROM dept20 WHERE sal > 2500
4 Union
5 SELECT ename3, sal FROM dept30 WHERE sal > 2500
6 Minus
7 SELECT ename , sal FROM emp WHERE job=‘PRESIDENT’
8 Order by 2,1;
ENAME SAL
---------- -------
BLAKE 2050
JONES 2975
FORD 3000
SCOTT 3000
SQL>
Обратите внимание, что при соединении нескольких запросов, можно использовать только одно предложениеORDERBY, причём оно должно находится только в последнем оператореSELECT.
Примечание. В данном примере первое возвращаемое поле имеет разное имя в каждом оператореSELECT, поэтому при сортировке вместо имён столбцов используются их порядковые номера.
В стандарте ANSIимеется предложениеFULL OUTER JOIN(и его сокращённая формаFULLJOIN), оно используется для полного объединения таблиц, т.е. по действию напоминает операторUNIONALL.
Дополнительные условия соединения по стандарту ANSI.
Стандарт ANSIдопускает формировать условие соединения не через предложениеON, а через предложениеNATURALлибо через предложениеUSING.
Предложение NATURALозначает, что в обоих таблицах берутся столбцы с одинаковыми именами (псевдонимы для столбцов игнорируются) и накладывается условие попарного равенства этих столбцов. Например, вместо
SELECT ename, dname
FROM emp INNER JOIN dept
ON emp.deptno = dept.deptno;
можно написать
SELECT ename, dname
FROM emp NATURALINNER JOIN dept;
Заметим, что всё это красиво только для простых таблиц, если в таблицах много столбцов, то велика вероятность не заметить совпадения имён тех столбцов, которые вовсе и не надо объединять. Поэтому в литературе не рекомендуется использовать условие NATURAL, а рекомендуется использовать условиеUSING.
Предложение USINGпишется вместо предложенияON, и в нём явно перечисляются все столбцы, которые следует использовать для сравнения. Например, предыдущий операторSELECTмог быть записан и так:
SELECT ename, dname
FROM emp INNER JOIN dept
USING (deptno);
Подзапрос SQL
Это обычный запрос SELECT, вложенный в операторSELECT,UPDATEилиDELETE.
Он используется в качестве источника данных для раздела FROMили для разделаWHEREродительского оператора. (А как насчётHAVING?).
Подзапрос может быть вложенным, т.е. содержать внутри себя другие подзапросы. Глубина вложенности не ограничивается.
Типы подзапросов:
Возвращающие одно поле в одной строке
Возвращающие одно поле в нескольких строках (т.е. столбец)
Предусматривающие возврат нескольких полей в одной строке
Предусматривающие возврат нескольких полей в нескольких строках (т.е. таблица)
К типу “A”(возвращаетполе) можно применять все операторы сравнения (равно, больше, меньше и т.п.). Например:
SELECT ename, sal FROM emp
WHERE sal > (SELECT AVG(sal) FROM emp);
А если таблица пустая ?
А что будет со следующим оператором ?
SELECT ename, sal FROM emp
WHERE sal > (SELECT sal FROM emp WHERE deptno=10);
Подзапрос применяется если нужно выполнить групповую функцию вместе с полем. Например, запрос
SELECT ename, MAX(hiredate) FROM emp;
Будет ошибочным, а правильным будет
SELECT ename, hiredate FROM emp
WHERE hiredate = (SELECT MAX(hiredate) FROM emp);
Подзапросы типа “B”(возвращаютстолбец) применяются для сравнения только вместе с операторами “IN”, “ANY”, “ALL”.
Пример, список последних сотрудников по каждому отделу:
SELECT deptno, ename, hiredate FROM emp
WHERE hiredate IN (SELECT MAX(hiredate) FROM emp
GROUP BY deptno);
Пример, список сотрудников отдела 10, у которых зарплата больше, чем у любого из сотрудников отдела 20.
SELECT deptno, ename, sal FROM emp
WHERE deptno = 10
AND sal > ALL (SELECT sal FROM emp
WHERE deptno=20);
К подзапросам типа “C”(возвращаютстроку) могут применяться только сравнения типа «равно/неравно».
Например, найти старейших работников с минимальной зарплатой:
SELECT deptno, ename, hiredate, sal FROM emp
WHERE (hiredate, sal) =
(SELECT MIN(hiredate), MIN(sal) FROM emp);
Подзапросы типа “D”(много полей и много строк), условно делятся на:
Парные, где для всей пачки полей предусмотрен один подзапрос
SELECT ename, job, sal FROM emp
WHERE (job,sal) IN (SELECT job, sal FROM emp
WHERE deptno=20);
Непарные, где для разных полей могут иметься разные подзапросы
SELECT ename, job, sal FROM emp
WHERE job IN (SELECT job FROM emp WHERE deptno=20)
AND sal IN (SELECT sal FROM emp WHERE deptno=20);
Пример применения подзапроса во фразе FROM: список сотрудников, имеющих зарплату ниже средней по своему отделу.
SELECT b.deptno, a.ename, a.sal
FROM emp a, (SELECT deptno, AVG(sal) AVG_SAL
FROM emp
GROUP BY deptno) b
WHERE a.deptno = b.deptno
AND a.sal < b.AVG_SAL);
Связанный (или коррелированный) подзапрос.
Связывает таблицы во внешнем и внутреннем подзапросе.
Например, можно получить тот же список сотрудников, имеющих зарплату ниже средней по своему отделу (но не отсортированный), так:
SELECT deptno, ename, sal
FROM emp a
WHERE sal < (SELECT AVG(sal)
FROM emp b
WHERE a.deptno = b.deptno);
Использование в запросах псевдостолбца ROWNUM
Пример, посмотреть трёх сотрудников с наибольшими зарплатами (за исключением президента)
SELECT ename, sal
FROM (SELECT ename, sal
FROM emp
WHERE job <> ‘PRESIDENT’
ORDER BY sal DESC
WHERE ROWNUM <=3;
Более сложные методы формирования отчётов в SQL*Plus
Перекрёстно-табличный отчёт
ch7_xref.doc
Получается в результате сочетания в одном запросе команд COMPUTE, функцийSUMи фразыGROUPBY.
Примечания: данные вводятся через параметр, а в командеTTITLEиспользован символ “–” продолжения команды на следующую строку.
Установка значений переменных на основе информации, полученной из БД. Используется не только для формирования отчётов, но и для создания скриптов.
ch7_lvar.doc
Здесь характерно получение некоторой информации из БД и занесение её в переменные, а затем формирование строк с помощью оператора SELECT … FROM dual. Кроме того, здесь нет никаких заголовков – ни у страниц, ни у столбцов.
Создание отчёта типа главный/подчинённый.
ch7_mdet.doc
Вывод заголовков отменён, поскольку в отчётах такого типа заголовки SQL*Plusнежелательны (тут применяются свои).
Единственное назначение столбца DUMMY– это поддержание порядка строк в пределах основного поля сортировки.
А строка Break Onнужна для красоты.