booktown=# SELECT title FROM books
30oktown-# WHERE author_id = (SELECT id FROM authors)
booktown(# WHERE last_name='Geisel'
booktown(# AND first_name='Theodor Seuss');
title
The Cat in the Hat
Bartholomew and the Oobleck
(2 rows)
Оператор = сравнивает поле id подзапроса к таблице authors с полем author_id габлицы books. Подзапрос находит в таблице authors запись об авторе с именем c<Theodor Seuss» и фамилией «Geisel»; сравнивая поле id этой записи с полем Author_id таблицы books, мы отбираем все книги, написанные этим автором.
Построение подзапросов требует осторожности: чтобы результат запроса проверялся простым оператором, подзапрос должен возвращать только одну запись. Например, если использовать для выборки кода автора более общий запрос, возвращающий несколько записей, PostgreSQL выдаст сообщение об ошибке:
booktown=# SELECT title FROM books
booktown-# WHERE authoMd = (SELECT id FROM authors
booktown(# WHERE last_name ` 'G');
ERROR: More than one tuple returned by a subselect used as an expression.
Обычные операторы не могут сравнивать отдельную величину с несколькими шачениями, поэтому сравнение поля authoMd с несколькими полями приводит к ошибке. Проблема легко решается включением в подзапрос секции LIMIT 1, благодаря которой подзапрос никогда не вернет более одной записи.
Если требуется проверить присутствие отдельной величины в заданном наборе, замените оператор = ключевым словом IN. Подзапрос, приведенный в листинге 4.60, выбирает несколько значений, сравниваемых с полем author_id (для авторов, имена которых начинаются с букв А-Е). Сравнение осуществляется при юмощи ключевого слова IN. Средства поиска по регулярному выражению рассматриваются в разделе «Операторы» главы 5.