InterBase
SELECT [DISTINCT | ALL] {* | <val> [, <val>...]}
FROM <tableref> [, <tableref>...]
[WHERE <search_condition>]
[GROUP BY col [COLLATE collation] [, col [COLLATE collation]...]
[HAVING <search_condition>]
[UNION <select_expr>]
[PLAN <plan_expr>]
[ORDER BY <order_list>]
<tableref> = <joined_table> | table | view | procedure [(<val> [, <val>...])] [alias]
<joined_table> = <tableref> <join_type> JOIN <tableref> ON <search_condition> | (<joined_table>)
<join-type> = {[INNER] | {LEFT | RIGHT | FULL } [OUTER]}
<search_condition> = {<val> <operator>
{<val> | (<select_one>)}
| <val> [NOT] BETWEEN <val> AND <val>
| <val> [NOT] LIKE <val> [ESCAPE <val>]
| <val> [NOT] IN (<val> [, <val>...] | <select_list>)
| <val> IS [NOT] NULL
| <val> {[NOT] {= | < | >} | >= | <=} {ALL | SOME | ANY} (<select_list>)
| EXISTS (<select_expr>)
| SINGULAR (<select_expr>)
| <val> [NOT] CONTAINING <val>
| <val> [NOT] STARTING [WITH] <val>
| (<search_condition>)
| NOT <search_condition>
| <search_condition> OR <search_condition>
| <search_condition> AND <search_condition>}
<operator> = {= | < | > | <= | >= |!< |!> | <> |!=}
<select_one> = SELECT on a single column that returns exactly one row.
<select_list> = SELECT on a single column that returns zero or more rows.
<select_expr> = SELECT on a list of values that returns zero or more rows.
Рекурсивное связывание (SELF JOIN) предполагает связывание таблицы с ней же самой, как будто бы это были две таблицы, применяя временное переименование таблицы в операторе SQL. Синтаксис такого оператора следующий.
SELECT А.имя_столбца, В.имя_столбца [, С.имя_столбца ]
FROM таблица1 А, таблица2 В [, таблица3 С ]
WHERE А.имя_столбца = В.имя_столбца [ AND А.имя_столбца = С.имя_столбца ]
Например,
SELECT A.LAST_NAME, B.LAST_NAME, A.FIRST_NAME
FROM EMPLOYEE_TBL A, EMPLOYEE_TBL В
WHERE A.LAST_NAME = B.LAST_NAME;
Этот оператор SQL возвратит имена всех служащих с одинаковыми фамилиями из таблицы EMPLOYEE_TBL. Рекурсивное связывание удобно использовать, когда все необходимые данные размещаются в одной таблице, но требуется каким-то образом сравнить одни записи таблицы с другими.
Часто использование рекурсивного связывания объясняется на следующем примере. Предположим, что имеется таблица, в которой хранятся табельный номер, имя служащего и табельный номер менеджера этого служащего, и предположим, что возникла необходимость получить список служащих вместе с именами их менеджеров. Проблема в том, что столбца с именами менеджеров в данной таблице нет – имеется только столбец с именами всех служащих.
SELECT ID, NAME, MNGR_ID FROM EMP;
1 JOHN 0
2 MARY 1
3 STEVE 1
4 JACK 2
5 SUE 2
Поэтому в следующем запросе таблица EMP в выражении ключевого слова FROM включена дважды и ей назначены два псевдонима. Имея два псевдонима, таблицу можно рассматривать как две разные таблицы. Все менеджеры являются также служащими, поэтому в условии связывания можно сравнить табельный номер служащего из «первой» таблицы с табельным номером менеджера из «второй» таблицы. Теперь «первая» таблица хранит информацию о служащих, а «вторая» – о менеджерах.
SELECT El.NAME, E2.NAME FROM EMP El, EMP E2 WHERE E1.MGR_ID = E2.ID;
NAME NAME
MARY JOHN
STEVE JOHN
JACK MARY
SUE MARY