2015-06-15 46 views
3

以逗號分隔的字符串存儲數據不取決於我,它不是我可以在我的數據庫中更改的東西,請耐心等待。我已經在線和在stackoverflow上進行了很多搜索,但是我找不到解決方案,如果甚至可以使用MySQL。如何用另一個表中的匹配值替換/更新列中每個字符串的所有實例?

我想用table2中的匹配值替換table1中每個唯一字符串的所有實例。我試過通配符,替換,更新,加入等,我只是不知道如何使它工作。我知道一個解決方案將替換()爲每個字符串,但table2有超過200行,這意味着嵌套超過200次。

這是我正在努力完成的。我有兩個表,表1:

+------+-------------+ 
| Item | Code  | 
+------+-------------+ 
| 1 | 614   | 
+------+-------------+ 
| 2 | 212,614,415 | 
+------+-------------+ 
| 3 | 212,303  | 
+------+-------------+ 
| ... | ...   | 
+------+-------------+ 

和表2:

+------+-------------------+ 
| Code | Name    | 
+------+-------------------+ 
| 614 | Columbus, OH  | 
+------+-------------------+ 
| 212 | New York, NY  | 
+------+-------------------+ 
| 415 | San Francisco, CA | 
+------+-------------------+ 
| 303 | Ft. Worth, TX  | 
+------+-------------------+ 
| ... | ...    | 
+------+-------------------+ 

我想從表2的相應值來代替從表1代碼產生這樣的結果:

+------+---------------------------------------------+ 
| Item | Code          | 
+------+---------------------------------------------+ 
| 1 | Columbus, OH        | 
+------+---------------------------------------------+ 
| 2 | New York, NY,Columbus, OH,San Francisco, CA | 
+------+---------------------------------------------+ 
| 3 | New York, NY,Ft. Worth, TX     | 
+------+---------------------------------------------+ 
| ... | ...           | 
+------+---------------------------------------------+ 
+0

您是否嘗試過光標?您可以使用光標輕鬆更新每個單元格 –

回答

1

這應該這樣做(請參閱下面的最後一個查詢)。我已將逗號包含在連接中,因此,12之類的內容與id不匹配,例如212(例如)。

drop table if exists table1; 

drop table if exists table2; 

create table table1(
    item int, 
    code varchar(64) 
); 

create table table2(
    code int, 
    name varchar(64) 
); 

insert into table1 values (1, '614'); 
insert into table1 values (2, '212,614,415'); 
insert into table1 values (3, '212,303'); 

insert into table2 values(212, 'New York, NY'); 
insert into table2 values(303, 'Ft. Worth, TX'); 
insert into table2 values(415, 'San Francisco, CA'); 
insert into table2 values(614, 'Columbus, OH'); 

select * from table1 

+ --------- + --------- + 
| item  | code  | 
+ --------- + --------- + 
| 1   | 614  | 
| 2   | 212,614,415 | 
| 3   | 212,303 | 
+ --------- + --------- + 
3 rows 

select * from table2 

+ --------- + --------- + 
| code  | name  | 
+ --------- + --------- + 
| 212  | New York, NY | 
| 303  | Ft. Worth, TX | 
| 415  | San Francisco, CA | 
| 614  | Columbus, OH | 
+ --------- + --------- + 
4 rows 

select 
    t1.item, 
    t2.name 
from 
    table1 t1 join table2 t2 on (
     t1.code = t2.code 
     or t1.code like concat(t2.code, ',%') 
     or t1.code like concat('%,', t2.code, ',%') 
     or t1.code like concat('%,', t2.code) 
    ) 
order by t1.item 

+ --------- + --------- + 
| item  | name  | 
+ --------- + --------- + 
| 1   | Columbus, OH | 
| 2   | Columbus, OH | 
| 2   | New York, NY | 
| 2   | San Francisco, CA | 
| 3   | Ft. Worth, TX | 
| 3   | New York, NY | 
+ --------- + --------- + 
6 rows 

編輯: 或者如果你想保持非規範化像這樣的數據:

select 
    t1.item, 
    group_concat(t2.name) 
from 
    table1 t1 join table2 t2 on (
     t1.code = t2.code 
     or t1.code like concat(t2.code, ',%') 
     or t1.code like concat('%,', t2.code, ',%') 
     or t1.code like concat('%,', t2.code) 
    ) 
group by t1.item 
order by t1.item 

+ --------- + -------------------------- + 
| item  | group_concat(t2.name)  | 
+ --------- + -------------------------- + 
| 1   | Columbus, OH    | 
| 2   | Columbus, OH,New York, NY,San Francisco, CA | 
| 3   | Ft. Worth, TX,New York, NY | 
+ --------- + -------------------------- + 
3 rows 
+1

我試過你的方式,並在這裏張貼的其他方式之一。我有兩個工作,但我無法表達這種方式更簡單。節省了大量的時間。謝謝! –

+1

不錯。我認爲concat('%,',t2.code,'%')需要concat('%,',t2.code,',%'),是不是?這是在追蹤%之前添加逗號。 –

+0

@Karl Kieninger ......你是正確的先生。它最初編寫的方式會得到錯誤的命中(例如,如果您正在查找id = 12並且有100,122個,您將在那裏找不到該記錄)。我將編輯答案以反映您的更正。 – John

0

而且這裏我們看到一個完美的例子,爲什麼在數據庫字段中使用逗號分隔的列表是一個糟糕的主意。他們比正確的關係表更難以操縱。

考慮到這一點,我會考慮首先將代碼分成多個記錄,然後做簡單的基於替換,然後把它們放回到一起。基本上:

  1. 使用split function以產生具有1個記錄每個項目/代碼對臨時表TMP1。

  2. 然後對從tmp1加入到table1的tmp1.code執行UPDATE。

  3. 最後使用GROUP_CONCAT將名稱放在一起。

+0

我花了很多額外的研究來弄清楚拆分函數/存儲過程/光標部分,但這是我完成工作的有效方法。謝謝! –

相關問題