Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
以子查询为条件从中删除MySQL_Mysql_Sql_Subquery_Sql Delete_In Subquery - Fatal编程技术网

以子查询为条件从中删除MySQL

以子查询为条件从中删除MySQL,mysql,sql,subquery,sql-delete,in-subquery,Mysql,Sql,Subquery,Sql Delete,In Subquery,我正在尝试这样的查询: 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 =

我正在尝试这样的查询:

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
);
正如您可能知道的,如果同一tid有其他父项,我想删除与1015的父项关系。但是,这会产生一个语法错误:

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语句中再次引用别名,如:

DELETE th FROM term_hierarchy AS th
....

不能指定要删除的目标表

变通办法

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

别名应包含在DELETE关键字之后:


对于那些在使用子查询时发现这个问题想要删除的人,我给你们留下这个例子,让你们比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将很乐意满足您的要求。

我以一种稍微不同的方式处理这个问题,它对我很有效

我需要从引用条件表的表中删除secure_链接,其中不再剩下任何条件行。基本上是一个内务脚本。这给了我一个错误-您不能指定要删除的目标表

所以在这里寻找灵感,我提出了下面的问题,效果很好。 这是因为它创建了一个临时表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`
            )

对我有用。

不是删除中的in子句。。。如果子查询返回了大量的值,效率会非常低吗?不知道为什么您不只是从要删除的ID上的子查询中对原始表进行内部或右键联接,而不是在子查询中对我们进行联接

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。澄清了删除/加入问题。

如果你想通过两个查询来实现这一点,你总是可以做类似的事情:

1从表中抓取ID,包括:

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: 它按预期工作

然而,我想知道表中有数百万行的时间复杂性是什么?显然,在一个索引正确的表上有5k条记录需要大约5ms才能执行

我的问题是:

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语句中使用别名

DELETE  th.*
FROM term_hierarchy th
INNER JOIN term_hierarchy th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
WHERE th.parent = 1015;

不是关于alias的,请检查OPagain@ajreal-是的,请注意错误从别名定义开始,MySQL文档明确指出您需要在DELETE语句以及FROM子句中使用别名。不过,感谢您的否决票。只需从您的_表中删除t1,其中t1.id插入从您的_表t2中选择t2.id;你得到了什么?文件清楚地说明;当前,不能从表中删除,也不能从子查询中的同一表中选择。您不必修复别名,只需在delete中不指定要选择的目标表……这是真正的问题,我们都是对的——请参阅下面他对我答案的评论。别名语法和逻辑都有问题:是的,似乎通过子查询删除在MySQL中目前是不可能的——感谢您的关注:从term_hierarchy中删除和最后一行中的th不是有同样的问题吗?我得到了一个与OP相同的语法错误。您应该将索引添加到术语_hierarchy_backup.tid中。我能够验证这一点,2019年在MariaDB 10.3.14或MySQL Community Server 5.7.27上都不可能,但我花了一些时间让它工作。重要提示:1第一个表必须使用e作为别名,2结尾的x不是占位符,它是由子查询SELECT id FROM table(其中arg=1,foo=bar)生成的临时表的别名。为什么这样做?这对我来说变化很大,但更重要的是,它不应该起作用。它确实有效,但不应该。难以置信。这确实有效!但您不必将表别名为e。。。您可以使用任何您想要的别名。@jakabadambalazs我的推理是,以SELECT id开头的子查询将完成并返回一个id列表,从而释放您要从中删除的表的锁。@jakabadambalazs:我们不能在delete及其子SELECT中使用相同的表e。但是,我们可以使用子选择来创建临时表x,并将其用于子选择。这是一个很好的答案。正确的别名将大大有助于解决与原始帖子类似的问题。和我一样。注意:下面的答案很好,只需在从表t中删除t后添加表别名…与上面@CodeReaper中的相同。。。 很好的电话;
DELETE  th.*
FROM term_hierarchy th
INNER JOIN term_hierarchy th2 ON (th1.tid = th2.tid AND th2.parent != 1015)
WHERE th.parent = 1015;