В сервер MySQL поддерживает
вложенные запросы вида INSERT ...
SELECT ... и REPLACE ... SELECT
.... В других контекстах можно
использовать и функцию
IN().
Вложенные операции выборки реализованы в версии 4.1.
Между тем, во многих случаях можно переписать запрос, чтобы не использовать вложенную выборку. Например, запрос:
SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);
можно переписать следующим образом:
SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;
Запросы:
SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2
WHERE table1.id=table2.id);
эквивалентны следующему:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;
Для более сложных подзапросов
часто можно создать временные
таблицы, содержащие данный
подзапрос. Иногда, однако, этот
способ не годится, чаще всего для
команд DELETE, для которых
в стандарте SQL не поддерживаются
объединения (за исключением
вложенных выборок). В этой
ситуации возможны два временных
(пока вложенные запросы не
поддерживаются сервером MySQL)
варианта решения проблемы.
Первый вариант следующий: при
помощи какого-либо
процедурно-ориентированного
языка программирования (такого
как Perl или PHP) делается запрос
SELECT для получения
первичных ключей тех записей,
которые должны быть удалены, а
затем полученные величины
используются для составления
команды DELETE (DELETE FROM ... WHERE ... IN
(key1, key2, ...)).
Второй вариант предполагает
применение диалогового SQL для
автоматического создания набора
команд DELETE с
использованием расширения MySQL
CONCAT() (вместо
стандартного оператора
||). Например:
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';')
FROM tab1, tab2
WHERE tab1.col1 = tab2.col2;
Можно поместить этот запрос в файл скрипта, перенаправить стандартный вход клиента командной строки с этого файла, а стандартный выход - на еще один экземпляр клиента командной строки:
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
Сервер версии MySQL 4.0 поддерживает многотабличные удаления - эту функцию можно использовать для эффективного удаления строк как из одной таблицы, так и из нескольких одновременно
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.
© 1995-2005 MySQL AB. All rights reserved.
