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
)