2010-12-17 85 views
59

我試圖做一個查詢這樣的:MySQL的DELETE FROM與子查詢的條件

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不允許將您要刪除的表用於條件的子查詢中。

+1

**注意**:好的答案在底部http://stackoverflow.com/a/4471359/956397只需在DELETE t FROM table t之後添加表別名...' – PiTheNumber 2014-07-24 10:06:32

回答

28

您不能指定目標表刪除。

一種解決方法

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); 
+0

我們都是對的 - 請參閱他的評論以下我的答案。別名的語法和邏輯都是問題:) – JNK 2010-12-17 14:51:27

+0

是啊,似乎通過子查詢刪除目前在MySQL中是不可能的 - 感謝您看看它:) – mikl 2010-12-17 14:51:44

+0

不會在最後一行中的「DELETE FROM term_hierarchy AS th」具有同樣的問題?我得到的語法錯誤與OP相同。 – malhal 2012-01-24 20:02:55

6

您需要在delete語句中再次引用別名,如:

DELETE th FROM term_hierarchy AS th 
.... 

As outlined here in MySQL docs.

+0

不是別名,請再次檢查OP – ajreal 2010-12-17 14:24:20

+0

@ajreal - 我做過了,請注意錯誤從別名定義開始,並且MySQL文檔明確聲明您需要在DELETE語句以及FROM子句中使用別名。儘管感謝downvote。 – JNK 2010-12-17 14:25:19

+0

只要做到這一點'從你的表中刪除你的表t1,其中t1.id in(從your_table t2選擇t2.id);'你得到了什麼? – ajreal 2010-12-17 14:27:14

30

別名應包含在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 
); 
+2

這是一個很好的答案。適當的別名將大大解決類似於原始帖子的問題。 (像我的。) – usumoio 2013-12-04 21:02:33

188

對於其他人發現這個問題看,同時使用子查詢,刪除,我離開你這個例子超過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); 

會工作得很好:

Query OK, 1 row affected (3.91 sec) 

環繞你的子查詢了在其他子查詢(這裏命名爲x) MySQL會很樂意做你所要求的。

+7

花了一些時間,但我得到它的工作。重要說明:1)第一個表必須如此處所示的別名爲「e」,2)末尾的「x」不是佔位符,它是由子查詢生成的臨時表的別名「(SELECT id FROM tableE WHERE arg = 1 AND foo ='bar')「。 – 2013-03-08 11:28:26

+3

這是爲什麼工作?這對我來說有很大的改變,但是,它不應該起作用。它*做*工作,但它不應該。 – donatJ 2014-04-14 21:53:07

+1

令人難以置信。這實際上有效!但是你不會被迫使用e來替換表...你可以使用任何你想要的別名。 – 2014-04-29 13:37:00

4

我以一種稍微不同的方式接近這個,它對我有用;

我需要從我的表中刪除secure_links引用conditions表,其中不再有任何條件行左。一個家政腳本基本上。這給了我錯誤 - 你不能指定目標表進行刪除。

所以在這裏尋找靈感我想出了下面的查詢,它工作得很好。 這是因爲它創建了一個用作DELETE參考的臨時表sl1

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` 
      ) 

適合我。

3

是不是刪除中的「in」子句...如果從子查詢中返回大量的值,效率極低?不知道爲什麼你不會爲了刪除而不是內部(或右邊)從子查詢中反向刪除原始表,而不是我們的「in(subquery)」。

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不允許它」,但是,它工作正常,我提供的我一定要完全弄清楚刪除的內容(DELETE FROM牛逼目標AS T)。 Delete with Join in MySQL闡明DELETE/JOIN問題。

0

如果你想與2個查詢要做到這一點,你總是可以做同樣的事情到這一點:

1)抓住IDS從表:

SELECT group_concat(id) as csv_result FROM your_table WHERE whatever = 'test' ... 

然後複製用鼠標/鍵盤導致或編程語言爲XXX:

2) DELETE FROM your_table WHERE id IN (XXX) 

也許你可以在一個查詢中做到這一點,但這是我更喜歡的。