MySql:使用最少的表子集更新表

时间:2014-08-28 17:25:24

标签: mysql sql-update subquery

这是我的测试数据库:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
    PRIMARY KEY (`id`),
    `parent` int(10) unsigned DEFAULT NULL, 
    `number` int DEFAULT NULL
) ENGINE=InnoDB;

INSERT INTO t1 SET id=1, parent=NULL, number=NULL;
INSERT INTO t1 SET id=2, parent=NULL, number=NULL;
INSERT INTO t1 SET id=3, parent=NULL, number=NULL;

INSERT INTO t1 SET parent=1, number=4;
INSERT INTO t1 SET parent=1, number=2;
INSERT INTO t1 SET parent=1, number=3;

INSERT INTO t1 SET parent=2, number=10;
INSERT INTO t1 SET parent=2, number=20;
INSERT INTO t1 SET parent=2, number=30;

INSERT INTO t1 SET parent=3, number=3;
INSERT INTO t1 SET parent=3, number=2;
INSERT INTO t1 SET parent=3, number=1;

我正在尝试将每个父母的“数字”设置为其子女“数字”的最小值:

UPDATE t1 
SET number=(SELECT min(number) FROM t1 AS t2 WHERE t1.id=t2.parent) 
WHERE t1.parent IS NULL;

但是这给了我一个错误: ERROR 1093(HY000):您无法在FROM子句

中为更新指定目标表't1'

我理解这是一种加入的方式,但我说得不对:

UPDATE t1 
LEFT JOIN
    (SELECT min(t2.number) AS minnumber, t2.parent AS parent FROM t1 AS t2) t2
ON t1.id = t2.parent
SET t1.number = t2.minnumber
WHERE t1.parent IS NULL;

但是之后id1,id2,id3的“数字”只是NULL。我假设这是因为在JOIN中我不能限制t2仅在实际的父项上工作,所以它适用于整个表。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

看起来您需要在内联视图查询(GROUP BY)中添加t2子句,以便为每个parent返回一行。

如果没有GROUP BY子句,该查询将返回单行。 (你可以只运行t2查询,看看。)

当我们添加GROUP BY子句时,我们应该返回parent返回的所有不同值,以及与每个父级关联的最小number

SELECT MIN(t2.number) AS minnumber
     , t2.parent AS parent 
  FROM t1 t2
 GROUP BY t2.parent