Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.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:您不能在FROM子句中为更新指定目标表'list'_Mysql - Fatal编程技术网

MySQL:您不能在FROM子句中为更新指定目标表'list'

MySQL:您不能在FROM子句中为更新指定目标表'list',mysql,Mysql,我正在尝试运行以下查询: update list set li = '6' where li = '5' and dn in ( SELECT dn FROM list GROUP BY dn HAVING COUNT(*) < 2000 ) 所以我从一位建议我运行以下程序的人那里得到了建议: START TRANSACTION; UPDATE list a INNER JOIN ( SELECT dn FROM list

我正在尝试运行以下查询:

update list
set li = '6'
where li = '5'
and dn in ( SELECT dn FROM list GROUP BY dn HAVING COUNT(*) < 2000 )
所以我从一位建议我运行以下程序的人那里得到了建议:

START TRANSACTION;
UPDATE  list a
    INNER JOIN
    (
        SELECT  dn 
        FROM    list 
        GROUP   BY dn 
        HAVING  COUNT(*) < 2000 
    ) b ON a.dn = b.dn
SET     a.li = '6'
WHERE   a.li = '5';
这段代码运行-问题是它永远不会结束。我不确定这是不是因为声明本身有问题,或者是因为它正在努力处理400万条记录,但我昨晚睡觉的时候把它忘了,今天早上它还没完成。还有,这只是事后的一个想法:我确实尝试过将其应用到事务中,以防事情变得一团糟,从而导致“启动事务;”一开始

我觉得这在这里是一个相当常见的问题,但不幸的是,我对SQL不够了解,无法接受其他人的查询并调整它以满足我自己的需要p


有谁能指导我找到一个解决方案,让我更新这些记录吗?非常感谢。

当我们试图更新一个表,并且在另一个查询中有相同的表来更新列时,会产生此错误

我们无法从您同时更新的表中进行选择。但是,我们可以进行多表更新,如

UPDATE tbl AS a
  INNER JOIN tbl AS b ON ....
  SET a.col = b.col
或者尝试您的查询的简化版本

update list l1, ( SELECT dn FROM list GROUP BY dn HAVING COUNT(*) < 2000 ) AS l2
set li = '6'
where li = '5'
and dn = l2.dn
希望能有帮助。。 这是给你的参考资料

查询:

update list
set li = '6'
where li = '5'
and dn in ( SELECT a.dn 
            FROM (SELECT * FROM list) a 
            GROUP BY a.dn 
            HAVING COUNT(*) < 2000 )
此查询可能会更快:

UPDATE list t
SET t.li = '6'
WHERE t.li = '5'
AND (SELECT COUNT(*)
     FROM (SELECT * FROM tik) a 
     WHERE a.dn = t.dn) < 2000

这可能行得通,因此,继续我上面的评论,下面是一个答案:

是的,删除“6”和“5”周围的引号,您不希望MySQL在每次比较时将li列转换为字符串。。。并创建一个索引

CREATE idx_dn_li ON list(dn, li);

UPDATE  list a
    INNER JOIN
    (
        SELECT  dn 
        FROM    list 
        GROUP   BY dn 
        HAVING  COUNT(*) < 2000 
    ) b ON a.dn = b.dn
SET     a.li = 6
WHERE   a.li = 5;

索引将使您的组更快,我认为在那里有li列也会有所帮助,因为我认为,在没有记录受到影响的情况下,您的查询应该只读取索引,但不要相信我的话

嗯。。只是问问。。你确定a.li='5'的位置吗,我的意思是它应该像a.li='5'的位置一样。结尾“”在实际查询中。您可能需要在SQL语句之后添加COMMIT。不确定MySQL是否自动提交。dn列上是否至少有索引?按该列分组肯定会很慢,否则。。。li列真的是VARCHAR类型吗?字符串比较很慢,如果你可以用一个整数列来代替它,你可以获得一些性能。好吧,关键是我可以在出现问题时回滚。在提交之前,我需要看到查询完成。默认情况下,我没有启用事务,这是我必须手动开始的。
CREATE idx_dn_li ON list(dn, li);

UPDATE  list a
    INNER JOIN
    (
        SELECT  dn 
        FROM    list 
        GROUP   BY dn 
        HAVING  COUNT(*) < 2000 
    ) b ON a.dn = b.dn
SET     a.li = 6
WHERE   a.li = 5;