DELETE
DELETE — удалить записи таблицы
Синтаксис
[ WITH [ RECURSIVE ]запрос_WITH[, ...] ] DELETE FROM [ ONLY ]имя_таблицы[ * ] [ [ AS ]псевдоним] [ USINGэлемент_FROM[, ...] ] [ WHEREусловие| WHERE CURRENT OFимя_курсора] [ RETURNING { * |выражение_результата[ [ AS ]имя_результата] } [, ...] ]
Описание
Команда DELETE удаляет из указанной таблицы строки, удовлетворяющие условию WHERE. Если предложение WHERE отсутствует, она удаляет из таблицы все строки, в результате будет получена рабочая, но пустая таблица.
Подсказка
TRUNCATE реализует более быстрый механизм удаления всех строк из таблицы.
Удалить строки в таблице, используя информацию из других таблиц в базе данных, можно двумя способами: применяя вложенные запросы или указав дополнительные таблицы в предложении USING. Выбор предпочитаемого варианта зависит от конкретных обстоятельств.
Предложение RETURNING указывает, что команда DELETE должна вычислить и возвратить значения для каждой фактически удалённой строки. Вычислить в нём можно любое выражение со столбцами целевой таблицы и/или столбцами других таблиц, упомянутых в USING. Список RETURNING имеет тот же синтаксис, что и список результатов SELECT.
Чтобы удалять данные из таблицы, необходимо иметь право DELETE для неё, а также право SELECT для всех таблиц, перечисленных в предложении USING, и таблиц, данные которых считываются в условии.
Параметры
запрос_WITHПредложение
WITHпозволяет задать один или несколько подзапросов, на которые затем можно ссылаться по имени в запросеDELETE. Подробнее об этом см. Раздел 7.8 и SELECT.имя_таблицыИмя (возможно, дополненное схемой) таблицы, из которой будут удалены строки. Если перед именем таблицы добавлено
ONLY, соответствующие строки удаляются только из указанной таблицы. БезONLYстроки будут также удалены из всех таблиц, унаследованных от указанной. При желании, после имени таблицы можно указать*, чтобы явно обозначить, что операция затрагивает все дочерние таблицы.псевдонимАльтернативное имя целевой таблицы. Когда указывается это имя, оно полностью скрывает фактическое имя таблицы. Например, в запросе
DELETE FROM foo AS fдополнительные компоненты оператораDELETEдолжны обращаться к целевой таблице по имениf, а неfoo.элемент_FROMТабличное выражение, позволяющее добавить в условие
WHEREстолбцы из других таблиц. В этом выражении используется тот же синтаксис, что и в предложенииFROMоператораSELECT; например, в нём можно определить псевдоним для таблицы. Повторять в нём имя целевой таблицы нужно, только если требуется определить замкнутое соединение (в этом случае для данного имени должен определяться псевдоним).условиеВыражение, возвращающее значение типа
boolean. Удалены будут только те строки, для которых это выражение возвращаетtrue.имя_курсораИмя курсора, который будет использоваться в условии
WHERE CURRENT OF. С таким условием будет удалена строка, выбранная из этого курсора последней. Курсор должен образовываться запросом, не применяющим группировку, к целевой таблице командыDELETE. Заметьте, чтоWHERE CURRENT OFнельзя задать вместе с логическим условием. За дополнительными сведениями об использовании курсоров сWHERE CURRENT OFобратитесь к DECLARE.выражение_результатаВыражение, которое будет вычисляться и возвращаться командой
DELETEпосле удаления каждой строки. В этом выражении можно использовать имена любых столбцов таблицыимя_таблицыили таблиц, перечисленных в спискеUSING. Чтобы получить все столбцы, достаточно написать*.имя_результатаИмя, назначаемое возвращаемому столбцу.
Выводимая информация
В случае успешного завершения, DELETE возвращает метку команды в виде
DELETE число
Здесь число — количество удалённых строк. Заметьте, что это число может быть меньше числа строк, соответствующих условию, если удаления были подавлены триггером BEFORE DELETE. Если число равно 0, это означает, что запрос не удалил ни одной строки (это не считается ошибкой).
Если команда DELETE содержит предложение RETURNING, её результат будет похож на результат оператора SELECT (с теми же столбцами и значениями, что содержатся в списке RETURNING), полученный для строк, удалённых этой командой.
Примечания
Postgres Pro позволяет ссылаться на столбцы других таблиц в условии WHERE, когда эти таблицы перечисляются в предложении USING. Например, удалить все фильмы определённого продюсера можно так:
DELETE FROM films USING producers WHERE producer_id = producers.id AND producers.name = 'foo';
По сути в этом запросе выполняется соединение таблиц films и producers, и все успешно включённые в соединение строки в films помечаются для удаления. Этот синтаксис не соответствует стандарту. Следуя стандарту, эту задачу можно решить так:
DELETE FROM films WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
В ряде случаев запрос в стиле соединения легче написать и он может работать быстрее, чем в стиле вложенного запроса.
Примеры
Удаление всех фильмов, кроме мюзиклов:
DELETE FROM films WHERE kind <> 'Musical';
Очистка таблицы films:
DELETE FROM films;
Удаление завершённых задач с получением всех данных удалённых строк:
DELETE FROM tasks WHERE status = 'DONE' RETURNING *;
Удаление из tasks строки, на которой в текущий момент располагается курсор c_tasks:
DELETE FROM tasks WHERE CURRENT OF c_tasks;
Несмотря на отсутствие предложения LIMIT для команды DELETE, можно ограничить число удаляемых строк, использовав метод в описании команды UPDATE:
WITH delete_batch AS (
SELECT l.ctid FROM user_logs AS l
WHERE l.status = 'archived'
ORDER BY l.creation_date
FOR UPDATE
LIMIT 10000
)
DELETE FROM user_logs AS dl
USING delete_batch AS del
WHERE dl.ctid = del.ctid;Совместимость
Эта команда соответствует стандарту SQL, но предложения USING и RETURNING являются расширениями Postgres Pro, как и возможность использовать WITH с DELETE.