鉴于这些表没有先前的关系:
*codes* *people*
id label id type code_id
1 1 1 2 X
2 1 2 2 X
3 1 3 7 X
4 2
5 2
我想更新表people
从codes
表中选择值。我需要来自people
label=2
{{}}}的每个项目与codes
的ID不同。由于代码多于人,因此不会有人共享代码。
所以例如结果是
*people*
id type code_id
1 2 4 # updated with one value from codes table
2 2 5 # updated with another value from codes table
3 7 X # not updated, as type<>2
我已对此进行了测试,但在使用WHERE
过滤器时无效:
UPDATE people A
INNER JOIN
(SELECT id FROM codes WHERE label=2) B
USING (id)
SET A.code_id=B.id
WHERE A.type=2;
我做错了什么?
对于那些检查问题的人,我准备了要在SQL Fiddle中测试的代码,如下所示:
CREATE TABLE codes (id int auto_increment primary key, label int);
CREATE TABLE people (id int auto_increment primary key, type int, code_id int);
INSERT INTO codes VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
INSERT INTO people (id,type) VALUES (1,2),(2,2),(3,7);
答案 0 :(得分:1)
您可以使用CURSORs让它工作(这样您就可以逐行遍历代码表复制结果)。像这样:
CREATE PROCEDURE updatecodes()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a,b INT;
DECLARE cur1 CURSOR FOR SELECT id FROM codes WHERE label = 2;
DECLARE cur2 CURSOR FOR SELECT id FROM people WHERE type = 2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO a;
FETCH cur2 INTO b;
IF done THEN
LEAVE read_loop;
END IF;
UPDATE people SET code_id = a WHERE id = b;
END LOOP;
CLOSE cur1;
CLOSE cur2;
END
然后只是
CALL updatecodes();
如果我有链接权限,那么应该有一个更新的SQL小提琴:SQL Fiddle
答案 1 :(得分:1)
您也可以这样做......
SELECT x.id,x.type, y.id code_id
FROM
( SELECT a.*
, COUNT(*) rank
FROM people a
JOIN people b
ON b.type = a.type
AND b.id <= a.id
GROUP
BY type, id
) x
JOIN
( SELECT a.*
, COUNT(*) rank
FROM codes a
JOIN codes b
ON b.label = a.label
AND b.id <= a.id
GROUP
BY label
, id
) y
ON y.label = x.type
AND y.rank = x.rank;
...或重写为更新......
UPDATE people p
JOIN
( SELECT a.*
, COUNT(*) rank
FROM people a
JOIN people b
ON b.type = a.type
AND b.id <= a.id
GROUP
BY type, id
) x
ON x.id = p.id
JOIN
( SELECT a.*
, COUNT(*) rank
FROM codes a
JOIN codes b
ON b.label = a.label
AND b.id <= a.id
GROUP
BY label
, id
) y
ON y.label = x.type
AND y.rank = x.rank
SET p.code_id = y.id;