0

我想通过从一个表中选择一个值到另一个表中来链接两个表,它们之间没有以前的关系。

所以我的桌子是:

代码:

ID 标签
1 1
2 1
3 1
4 2
5 2

人们:

ID 类型 code_id
1 2 X
2 2 X
3 7 X

我想people从表中更新表选取值codes。每当一个项目 frompeople具有条件label=2时,它就需要从 中选择一个不同的 id codes。“代码”中的代码比“人”中的人多,因此每个人都可以有不同的代码。

因此,例如结果是:

ID 类型 code_id 解释
1 2 4 用代码表中的一个值更新
2 2 5 用代码表中的另一个值更新
3 7 X 没有更新,因为type<>2

WHERE我尝试过使用这样的 INNER JOIN,但是在使用过滤器时它不起作用:

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

2 回答 2

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;
于 2013-10-04T12:58:09.187 回答
1

您可以使用CURSOR使其工作(因此您可以逐行遍历代码表,每次复制结果)。像这样的东西:

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 Fiddle:SQL Fiddle

于 2013-10-04T12:26:03.833 回答