Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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_Query Optimization_Mysql Error 1093 - Fatal编程技术网

使用自连接的MySQL更新查询比较困难

使用自连接的MySQL更新查询比较困难,mysql,sql,query-optimization,mysql-error-1093,Mysql,Sql,Query Optimization,Mysql Error 1093,我们的网站有列表。我们使用具有以下结构的连接表将我们的成员与这些不同的列表连接起来: CREATE TABLE `connections` ( `cid1` int(9) unsigned NOT NULL DEFAULT '0', `cid2` int(9) unsigned NOT NULL DEFAULT '0', `type` char(2) NOT NULL, `created` datetime DEFAULT NULL, `updated` datetime D

我们的网站有列表。我们使用具有以下结构的连接表将我们的成员与这些不同的列表连接起来:

CREATE TABLE `connections` (
  `cid1` int(9) unsigned NOT NULL DEFAULT '0',
  `cid2` int(9) unsigned NOT NULL DEFAULT '0',
  `type` char(2) NOT NULL,
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`cid1`,`cid2`,`type`,`cid3`),
  KEY `cid1` (`cid1`,`type`),
  KEY `cid2` (`cid2`,`type`)
);
update connections set cid2=100000
where type IN ('MC','MT','MW') AND cid2=100001;
我们遇到的问题是,当我们不得不不时地合并重复的列表时,我们还需要更新我们的成员连接,并且一直在使用以下查询,如果一个成员连接到两个列表,该查询将中断:

CREATE TABLE `connections` (
  `cid1` int(9) unsigned NOT NULL DEFAULT '0',
  `cid2` int(9) unsigned NOT NULL DEFAULT '0',
  `type` char(2) NOT NULL,
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`cid1`,`cid2`,`type`,`cid3`),
  KEY `cid1` (`cid1`,`type`),
  KEY `cid2` (`cid2`,`type`)
);
update connections set cid2=100000
where type IN ('MC','MT','MW') AND cid2=100001;
我想不出的是如何做到以下几点来解决这个问题:

update connections set cid2=100000
where type IN ('MC','MT','MW') AND cid2=100001 AND cid1 NOT IN (
    select cid1 from connections
    where type IN ('MC','MT','MW') AND cid2=100000
);
当我尝试运行该查询时,出现以下错误:

ERROR 1093 (HY000): You can't specify target table 'connections' for update in FROM clause
下面是一些示例数据。注意cid1=10025925的更新冲突

+----------+--------+------+---------------------+---------------------+
| cid1     | cid2   | type | created             | updated             |
+----------+--------+------+---------------------+---------------------+
| 10010388 | 100000 | MC   | 2010-08-05 18:04:51 | 2011-06-16 16:26:17 |
| 10025925 | 100000 | MC   | 2010-10-31 09:21:25 | 2010-10-31 16:21:25 |
| 10027662 | 100000 | MC   | 2011-06-13 16:31:12 | NULL                |
| 10038375 | 100000 | MW   | 2011-02-05 05:32:35 | 2011-02-05 19:51:58 |
| 10065771 | 100000 | MW   | 2011-04-24 17:06:35 | NULL                |
| 10025925 | 100001 | MC   | 2010-10-31 09:21:45 | 2010-10-31 16:21:45 |
| 10034884 | 100001 | MC   | 2011-01-20 18:54:51 | NULL                |
| 10038375 | 100001 | MC   | 2011-02-04 05:00:35 | NULL                |
| 10041989 | 100001 | MC   | 2011-02-26 09:33:18 | NULL                |
| 10038259 | 100001 | MC   | 2011-05-07 13:34:20 | NULL                |
| 10027662 | 100001 | MC   | 2011-06-13 16:33:54 | NULL                |
| 10030855 | 100001 | MT   | 2010-12-31 20:40:18 | NULL                |
| 10038375 | 100001 | MT   | 2011-02-04 05:00:36 | NULL                |
+----------+--------+------+---------------------+---------------------+

我希望有人能提出运行上述查询的正确方法。提前谢谢

一种可能的方法是为子查询使用临时表,然后从临时表中选择。如果你需要执行很多这样的任务,效率可能会很快下降

create temporary table subq as select cid1 from connections where type IN ('MC','MT','MW') AND cid2=100000


我是这样想的,但我不能百分之百确定你的数据在确定准确性之前和之后是什么样子的。这样做的目的是在子查询的
where
子句中将表本身连接起来,并且排除where
cid1
不能匹配

update connections c1 left outer join connections c2
 on (c2.cid2 = 100000 and c2.type in ('MC','MT','MW') and c1.cid1 != c2.cid1)
 set c1.cid2 = 100000
 where c1.type in ('MC', 'MT', 'MW') and c1.cid2=100001 and c2.cid1 is null;

据我所知,它会起作用的。我使用了您的
create table
(减去主键中的
cid3
),并确保有两行具有相同的
cid1
和不同的
cid2
(一行为100000,另一行为100001)并且该语句只影响1行。

查询中出现错误的原因是,在MySQL中,您无法从同一查询中尝试更新的表中进行选择

UPDATE connections cn1
LEFT JOIN connections cn2 ON cn1.cid1 != cn2.cid1
    AND cn2.type IN ('MC','MT','MW')
    AND cn2.cid2=100000
SET cn1.cid2=100000
WHERE cn1.TYPE IN ('MC','MT','MW') 
    AND cn1.cid2=100001 
    AND cn2.cid1 IS NULL -- i.e. there is no matching record
使用“更新忽略”避免重复冲突


我想你应该试着读一下重复键上的INSERT。我们的想法是,您构建一个插入查询,该查询总是创建重复的冲突,然后更新部分将完成它的部分。

谢谢,但不幸的是,它没有做到这一点。我试图遵循似乎正确的逻辑,但不确定问题是什么。由于某些原因,它似乎与正确的行不匹配(请参阅上面新添加的数据)。有时最好的解决方案是简单的解决方案。我在update语句中添加了ignore,然后用旧的cid2删除了所有剩余的行。非常感谢你的帮助!我知道这是非常古老的,但是有人知道为什么左外连接在这里更好吗?