ПОДЗАПРОСЫ

advertisement
ПОДЗАПРОСЫ
Что такое подзапрос?
Подзапрос - это команда SELECT, вложенная в предложение
другой команды SQL.
Главный
запрос
Синтаксис команды Select
Select…
Синтаксис
From…
Select
Where…
(Select…
From…
Where…)
Подзапрос
Подзапросы: синтаксис
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);


Подзапрос выполняется до выполнения главного запроса.
Результат подзапроса используется главным внешним
запросом.
Указания по использованию
подзапросов





Подзапрос должен быть заключен в скобки.
В подзапросах используются операторы сравнения двух
типов: однострочные и многострочные.
Подзапрос должен находиться справа от оператора.
Подзапросы могут использоваться во многих командах
SQL.
Подзапросы не могут содержать предложение ORDER BY.
ПРЕДЛОЖЕНИЯ КОМАНДЫ SELECT, В
КОТОРЫХ ИСПОЛЬЗУЮТСЯ
ПОДЗАПРОСЫ
 WHERE
 HAVING
 FROM
Подзапросы: пример
LAST_NAME
TITLE
-------------- ----------Maduro
Stock Clerk
Smith
Stock Clerk
Nozaki
Stock Clerk
Patel
Stock Clerk
Newman
Stock Clerk
Chang
Stock Clerk
Patel
Stock Clerk
Danca
Stock Clerk
Schwartz Stock Clerk
TITLE
----------Stock Clerk
LAST_NAME
----------Smith
Как обрабатываются
вложенные подзапросы?
1
2
Вложенная команда SELECT выполняется первой.
Результат передается в условие главного запроса.
Вложенный запрос
SELECT dept_id
FROM s_emp
WHERE last_name='Biri'
Главный запрос
SELECT last_name, title
FROM s_emp
WHERE dept_id =
Предложение HAVING с
подзапросами



Подзапросы используются и в предложениях HAVING.
Сервер Oracle выполняет подзапросы первыми.
Сервер возвращает результаты в предложение HAVING
главного запроса.
SQL>
SELECT dept_id, AVG(salary)
2 FROM s_emp
3 GROUP ВY dept_id
4 HAVING AVG(salary) >
5
(SELECT AVG(salary)
6
FROM s_emр
7
WHERE dept_id = 32) ;
Однострочные подзапросы
SELECT last_name,title
FROM
s_emp
WHERE title =

Команда SQL для вывода
фамилии и должности
служащего
SELECT title
FROM
s_emp
WHERE last_name = ‘Smith’

SQL>
2
3
4
5
6

Команда SQL дпя
выяснения должности
сотрудника с фамилией
Smith
Соедините обе команды,
и пусть SQL определит
должность сотрудника с
фамилией Smith.
SELECT last_name, title
FROM s_emp
WHERE title =
(SELECT title
FROM s_emp
WHERE last_name = ‘Smith’);
Пример
Вывод фамилии, должности и заработной платы всех
сотрудников с заработной платой ниже средней.
SQL> SELECT last_name, title, salary
2 FROM s_emp
3 WHERE
salary <
4
(SELECT AVG (salary)
5
FROM s_emp);
LAST_NAME TITLE
SALARY
---------------- ----------------- -----Urguhart
Warehouse Manager
1200
Menchu
Warehouse Manager
1250
Biri
Warehouse Manager
1100
Smith
Stock Clerk
940
Nozaki
Stock Clerk
1200
Patel
Stock Clerk
795
Newman
Stock Clerk
750
Markarian Stock Clerk
850
Chang
Stock Clerk
800
Patel
Stock Clerk
795
Danes
Stock Clerk
860
Schwartz
Stock Clerk
1100
12 rows selected.
Многострочные подзапросы
• Возвращают более одной строки
• Используют многострочные операторы сравнения
Оператор
Значение
IN
Сравнение с любым элементом списка по
знаку сравнения «=»
ANY | SOME
Сравнение с любым значением,
возвращаемым подзапросом, по заданному
знаку сравнения
ALL
Сравнение со всеми значениями,
возвращаемыми подзапросом, по
заданному знаку сравнения
Ошибки в подзапросах

Если пишется подзапрос, возвращающий более одной
строки, и в нем используется однострочный оператор
сравнения, выдается сообщение об ошибке.
SQL> SELECT last_name, first_name, title
2 FROM e_emp
3 WHERE dept_id =
4 (SELECT ID
5
FROM s_dept
6 WHERE name = 'Finance’
7 OR region_id = 2) ;
ORA-01427:single-row subquery returns more
than one row

Для исправления измените этот оператор на
(многострочный оператор сравнения).
Многострочные подзапросы:
пример

Вместо оператора IN используется оператор =ANY.
SQL>
SELECT last_name, first_name, title
2 FROM s_emp
3 WHERE dept_id = ANY
4
(SELECT ID
5
FROM s_dept
6
WHERE name = 'Finance'
7
OR region_id = 2) ;
Использование оператора ANY
в многострочных подзапросах
SQL>
2
3
4
5
6
7
SELECT empno, ename, job
FROM emp
WHERE sal<ANY
(SELECT sal
FROM emp
WHERE job = ‘CLERK’)
AND job <> ‘CLERK’;
EMPNO
------7654
7521
ENAME
----------MARTIN
WARD
JOB
-----SALESMAN
SALASMAN
Использование оператора ALL
в многострочных подзапросах
SQL> SELECT empno, ename, job
2
FROM emp
3
WHERE sal>ALL
4
(SELECT avg(sal )
5
FROM emp
6
GROUP BY deptno);
EMPNO
------7839
7566
7902
7788
ENAME
----------KING
JONES
FORD
SCOTT
JOB
-----PRESIDENT
MANAGER
ANALYST
ANALYST
Многостолбцовые подзапросы
Главный запрос
MANAGER 10
Подзапрос
SALESMAN 30
MANAGER 10
CLERK
20
Главный запрос
производит
сравнение
MANAGER 10
с
значениями из многострочного
и многостолбцового
подзапроса
SALESMAN
MANAGER
CLARK
30
10
20
Использование
многостолбцовых
подзапросов
Вывод фамилии, номера отдела, оклада и комиссионных
всех служащих, оклад и комиссионные которых совпадают
как с окладом, так и с комиссионными одного и того же
служащего в отделе 30.
SQL> SELECT ename, deptno, sal, comm
2
FROM emp
3
WHERE (sal, NVL(comm,-1)) IN
4
(SELECT sal, NVL(comm,-1)
5
FROM emp
6
WHERE deptno = 30);
Сравнение столбцов
Парное
SAL
1600
1250
1250
2850
1500
950
Непарное
COMM
300
500
1400
0
SAL
1600
1250
1250
2850
1500
950
COMM
300
500
1400
0
Подзапрос с непарным
сравнением
Вывод фамилии, номера отдела, оклада и комиссионных
всех служащих, оклад и комиссионные которых совпадают с
комиссионными и окладом любого служащего в отделе 30.
SQL> SELECT ename, deptno, sal, comm
2
FROM emp
3
WHERE sal IN
(SELECT sal
4
FROM emp
5
WHERE deptno = 30)
6
AND
7
NVL(comm, -1) IN (SELECT NVL(comm,-1)
8
FROM emp
9
WHERE deptno=30);
Изменения таблицы EMP
 Предположим, что изменяются
оклады комиссионные Кларка
(Clark).
 Новый оклад - до 1500 долларов, в
новые комиссионные - до 300
долларов. SAL
ENAME
COMM
--------------…
CLARK
1500
…
ALLEN
1600
TURNER
1500
…
14 rows selected.
-----300
300
0
Подзапросы с парным сравнением
SQL> SELECT ename, deptno, sal, comm
2
FROM emp
3
WHERE (sal, NVL(comm, -1)) IN
4
(SELECT sal, NVL(comm, -1)
5
FROM emp
6
WHERE deptno = 30);
ENAME
DEPTNO
---------JAMES
30
WARD
30
MARTIN
30
TURNER
30
ALLEN
30
BLAKE
30
6 rows selected.
SAL
--950
1250
1250
1500
1600
2850
COMM
---500
1400
0
300
Подзапросы с непарным сравнением
SQL>
2
3
4
5
6
7
8
9
SELECT ename, deptno, sal, comm
FROM
emp
WHERE sal IN (SELECT sal
FROM emp
WHERE deptno = 30)
AND
NVL(comm, -1) IN (SELECT NVL(comm, -1)
FROM emp
WHERE deptno = 30);
ENAME
DEPTNO
---------JAMES
30
BLAKE
30
TURNER
30
CLARK
30
...
7 rows selected.
SAL
--950
2850
1500
1500
COMM
----
0
300
Неопределенное значение в
подзапросе
SQL> SELECT employee.ename
2
FROM emp employee
3
WHERE employee.empno NOT IN
4
(SELECT manager.mgr
5
FROM emp manager);
no rows selected.
Использование подзапроса в
предложении FROM
SQL>
2
3
4
5
6
SELECT a.ename, a.deptno, b.salavg
FROM
emp a, (SELECT deptno, avg(sal) salavg
FROM emp
GROUP BY deptno) b
WHERE a.deptno = b.deptno
AND
a.sal > b.salavg;
ENAME
SAL
---------KING
5000
JONES
2975
SCOTT
3000
...
6 rows selected.
DAPTNO
--10
20
20
SALAVG
---2916.6667
2175
2175
Коррелированные подзапросы:
синтаксис


Внутренний подзапрос ссылается на внешний запрос
Выполнение начинается с внешнего запроса
SELECT select_list
FROM table1 t_alias1
WHERE expr operator
(SELECT column_list
FROM table2 t_alias2
WHERE t_alias1.column operator
t_alias2.column);
Коррелированные подзапросы:
пример


Внутренний подзапрос ссылается на внешний запрос
Выполнение начинается с внешнего запроса
SQL>
2
3
4
5
6
SELECT deptno, ename, sal
FROM emp x
WHERE sal > (SELECT AVG(sal)
FROM emp
WHERE x.deptno = deptno)
ORDER BY deptno;
Квантифицированные
подзапросы


Использование операторов EXISTS и NOT EXISTS
Внешний запрос выполняется, если внутренний подзапрос
возвращает хотя бы одну строку
SQL> SELECT dname, deptno
2 FROM dept
3 WHERE NOT EXISTS
4
(SELECT * FROM emp
5
WHERE dept.deptno = emp.deptno);
Заключение



Подзапросы полезны для выборки данных по неизвестным
значениям.
Вложенный запрос содержит более одного предложения
SELECT.
Подзапросы обрабатываются первыми, после чего
выполняется основной запрос по результатам подзапроса,
переданным в предложение WHERE или HAVING.
SELECT select_list
FROM
table
WHERE expr operator
(SELECT select_list
FROM table);
Download