上线新功能,如何兼容旧数据?

sql 将一张表的字段复制到另一张表

我们在上线新功能后,有时修改了后台字段,需要兼容旧数据,得将一张表的字段复制到另一张表。
存在以下两种情况:

一、查询一张表B的字段,插入另一张表A。

格式如下:

INSERT INTO 表A(字段a1,字段a2)  SELECT 字段b1,字段b2  FROM 表B WHERE 字段b1=具体值;

示例:

INSERT INTO  t_taxtype(fpkid,fid,fdataid)  SELECT fpkid,fid,ftaxtype FROM t_risk WHERE ftaxtype='1';

如果字段需要计算后再复制,示例如下:

INSERT INTO  t_taxtype(fpkid,fid,fdataid)  SELECT friskid+1000000000 AS fpkid,fid,ftaxtype FROM t_risk WHERE ftaxtype='1';

二、查询一张表B的字段,更新另一张表A

可以使用UPDATE SET SELECT。

这个其实就叫做"多表关联更新"
假设A和B的关联关系为 B.字段b2=A.字段a2,格式如下:

UPDATE 表A A SET  A.字段a1 = (SELECT B.字段b1 FROM 表B B WHERE B.字段b2=A.字段a2)	;

示例如下:

UPDATE t_variable A SET  A.fvariable_number = (SELECT B.felement_id FROM t_element B WHERE B.fnumber=A.felement_number);

这样格式,在一般情况下可以生效。但是如果表B中满足条件的数据不存在,那么就在更新表A时可能会出错。
假设表A的字段a1需要更新,但是又不能为空,如果没有过滤掉表B字段b1中为null的数据,那么UPDATE时会报错"Column '字段a' cannot be null"。
更健壮的做法,可以判断表B中的数据是否存在,再去更新表A。

格式为UPDATE SET WHERE EXISTS,如下:

UPDATE 表A A 
SET  A.字段a1 = (SELECT B.字段b1 FROM 表B B WHERE B.字段b2=A.字段a2)	
WHERE EXISTS ( SELECT 1 FROM 表B B WHERE B.字段b2=A.字段a2);

这样可以从表B取出一行记录,检查WHERE条件,如果满足,则进行更新,即执行SET,若不满足,则取下一条记录,再检查WHERE条件,循环往复。

示例如下:

UPDATE t_variable A 
SET A.fvariable_number = ( SELECT B.felement_id FROM t_element B WHERE B.fnumber = A.felement_number ) 
WHERE EXISTS ( SELECT 1 FROM t_element B WHERE B.fnumber = A.felement_number );

UPDATE多表

想要查询一张表B的字段,更新另一张表A,也可以使用UPDATE多表。
在查询表B的字段时,要过滤掉为空/为null的数据,在Mysql中可以如下处理(Oracle不可以UPDATE多表):
将子查询的结果作为表C,并通过表C进行查询,最后UPDATE数据。
格式为:

UPDATE 表A A,
    ( SELECT B.字段b1 AS 字段c1 
    FROM 表B B 
    JOIN 表A A 
    ON A.字段a1 = B.字段b2) 表C 
SET A.字段a2 = C.字段c1 
WHERE C.字段c1  IS NOT NULL AND TRIM( C.字段c1  ) != '';

示例如下:

UPDATE t_variable v,
    ( SELECT e.fname AS fname 
    FROM t_element e 
    JOIN t_variable v 
    ON e.fnumber = v.felement_number ) n 
SET v.fvariable_number = n.fname 
WHERE n.fname IS NOT NULL AND TRIM( n.fname ) != '';

查询表B和表C的字段,更新另一张表A

如果是三张表,示例如下:

UPDATE t_variable v 
SET v.fnumber = (
    SELECT t.fname 
    FROM t_element_detail t
    JOIN t_element e ON e.fid = t.fid 
    WHERE e.fnumber = v.felement_number);

注意,在Mysql中,不能先select出同一表中的某些值,在同一语句中update这个表。
否则会报错:You can't specify target table '表名' for update in FROM clause。
以下这种写法是错误的:

UPDATE t_variable v
SET v.fnumber= 
    (
      SELECT t.fname
      FROM   t_variable v,t_element e ,t_element_detail t
      WHERE e.fnumber=v.felement_number AND e.fid=t.fid 
      ) 

posted on 2020-04-04 00:02  乐之者v  阅读(1055)  评论(0编辑  收藏  举报

导航