Я пытаюсь сделать такой запрос:
DELETE FROM term_hierarchy AS th
WHERE th.parent = 1015 AND th.tid IN (
SELECT DISTINCT(th1.tid)
FROM term_hierarchy AS th1
INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
WHERE th1.parent = 1015
);
Как вы, наверное, догадались, я хочу удалить родительское отношение к 1015, если у того же tid есть другие родители. Однако это дает мне синтаксическую ошибку:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS th
WHERE th.parent = 1015 AND th.tid IN (
SELECT DISTINCT(th1.tid)
FROM ter' at line 1
Я проверил документацию и запустил подзапрос сам по себе, и, похоже, все прошло проверку. Кто-нибудь может понять, что здесь не так?
Обновление : как указано ниже, MySQL не позволяет использовать таблицу, которую вы удаляете, в подзапросе для условия.
DELETE t FROM table t ...
Ответы:
Вы не можете указать целевую таблицу для удаления.
Обходной путь
create table term_hierarchy_backup (tid int(10)); <- check data type insert into term_hierarchy_backup SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015; DELETE FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN (select tid from term_hierarchy_backup);
источник
Для тех, кто считает этот вопрос желаемым удалить при использовании подзапроса, я оставляю вам этот пример для перехвата MySQL (даже если некоторые люди думают, что это невозможно сделать):
DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM tableE WHERE arg = 1 AND foo = 'bar');
выдаст вам ошибку:
ERROR 1093 (HY000): You can't specify target table 'e' for update in FROM clause
Однако этот запрос:
DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM (SELECT id FROM tableE WHERE arg = 1 AND foo = 'bar') x);
будет работать нормально:
Оберните свой подзапрос в дополнительный подзапрос (здесь он называется x), и MySQL с радостью сделает то, что вы просите.
источник
e
) в DELETE и в его под-SELECT. Мы можем , однако , использовать суб-суб-SELECT , чтобы создать временную таблицу (x
), и использование , что для суб-SELECT.Псевдоним должен быть включен после
DELETE
ключевого слова:DELETE th FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015 );
источник
Вам нужно снова обратиться к псевдониму в операторе удаления, например:
DELETE th FROM term_hierarchy AS th ....
Как указано здесь в документации MySQL.
источник
delete from your_table as t1 where t1.id in(select t2.id from your_table t2);
что у тебя получилось?Currently, you cannot delete from a table and select from the same table in a subquery.
dev.mysql.com/doc/refman/5.5/en/delete.htmlЯ подошел к этому несколько иначе, и у меня это сработало;
Мне нужно было удалить
secure_links
из моей таблицы ссылку наconditions
таблицу, в которой больше не осталось строк условий. По сути, сценарий домашнего хозяйства. Это дало мне ошибку - вы не можете указать целевую таблицу для удаления.В поисках вдохновения я пришел к следующему запросу, и он отлично работает. Это потому, что он создает временную таблицу,
sl1
которая используется в качестве ссылки для DELETE.DELETE FROM `secure_links` WHERE `secure_links`.`link_id` IN ( SELECT `sl1`.`link_id` FROM ( SELECT `sl2`.`link_id` FROM `secure_links` AS `sl2` LEFT JOIN `conditions` ON `conditions`.`job` = `sl2`.`job` WHERE `sl2`.`action` = 'something' AND `conditions`.`ref` IS NULL ) AS `sl1` )
Работает на меня.
источник
Разве предложение "in" в удалении ... где, крайне неэффективно, если из подзапроса будет возвращено большое количество значений? Не уверен, почему бы вам не просто внутренне (или правильно) присоединиться к исходной таблице из подзапроса по идентификатору для удаления, а не использовать «in (подзапрос)»?
DELETE T FROM Target AS T RIGHT JOIN (full subquery already listed for the in() clause in answers above) ` AS TT ON (TT.ID = T.ID)
И, возможно, на него ответят «MySQL не разрешает это», однако он у меня работает нормально. ПРЕДОСТАВЛЕНО. Я обязательно полностью прояснил, что нужно удалить (УДАЛИТЬ T ИЗ Target AS T). Удаление с соединением в MySQL проясняет проблему DELETE / JOIN.
источник
Если вы хотите сделать это с помощью двух запросов, вы всегда можете сделать что-то подобное:
1) возьмите идентификаторы из таблицы с помощью:
SELECT group_concat(id) as csv_result FROM your_table WHERE whatever = 'test' ...
Затем скопируйте результат с помощью мыши / клавиатуры или языка программирования в XXX ниже:
2) DELETE FROM your_table WHERE id IN ( XXX )
Возможно, вы могли бы сделать это одним запросом, но я предпочитаю это.
источник
@CodeReaper, @BennyHill: Работает, как ожидалось.
Тем не менее, мне интересно, какова временная сложность наличия миллионов строк в таблице? По-видимому, потребовалось около
5ms
выполнить, чтобы иметь 5 тыс. Записей в правильно проиндексированной таблице.Мой запрос:
SET status = '1' WHERE id IN ( SELECT id FROM ( SELECT c2.id FROM clusters as c2 WHERE c2.assign_to_user_id IS NOT NULL AND c2.id NOT IN ( SELECT c1.id FROM clusters AS c1 LEFT JOIN cluster_flags as cf on c1.last_flag_id = cf.id LEFT JOIN flag_types as ft on ft.id = cf.flag_type_id WHERE ft.slug = 'closed' ) ) x)``` Or is there something we can improve on my query above?
источник
вы можете использовать псевдоним таким образом в операторе удаления
DELETE th.* FROM term_hierarchy th INNER JOIN term_hierarchy th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th.parent = 1015;
источник