no-image

mysql 逗號分隔的id轉為逗號分隔的名稱(或者名稱轉id)

                                    

做APP,小程式就上開源眾包。世界盃期間免費領2600元啟動金。
>>>
  

今天處理一個需求,表欄位中存的是以逗號分割的code,另一張表中存放著code對應的code_name,現在又要要求把表中的欄位的code轉換成code_name並以逗號分割,形式和表欄位相同。

需求說明:​

達到的效果:

 

為了解決這個問題我就想到以前用sqlserver寫的split函式,準備拿過來修改下,結果發現兩個create function 語法不通,試圖修改了下然後發現MySQL貌似不支援表變數。這下完了,就不能把逗號分割的code以表的形式傳出來去匹配了。然後去網上找mysql的split函式發現怎麼這麼麻煩,寫一個函式,還要先建立兩個函式做鋪墊。果斷放棄了。

然後找了一些資料用mysql自帶的函式解決了這個問題

1、INSTR函式(INSTR相當於sqlserver的CharIndex函式)

INSTR(欄位名, 字串)

這個函式返回字串在某一個欄位的內容中的位置, 沒有找到字串返回0,否則返回位置(從1開始)

select GROUP_CONCAT(code_name) from t_fix_code

where INSTR((select engine_number from t_inventory_tmp where id =1 ),code)>0 and length(code)=8

雖然感覺貌似可以用了,但是有個問題就是如果以逗號分割的code在不通的長度都對應一個code_name的話匹配出來的結果會增多。還有instr函式子查詢只能返回一行,無法進行整表匹配。不過還是可以解決一條的問題。

就對INSTR重新運用了下

select a.engine_number,GROUP_CONCAT(b.code_name)

from t_inventory_tmp a

join t_fix_code b

on INSTR(a.engine_number,b.code)>0 and length(code)=8

group by a.engine_number

這個解決了問題但是條件裡面有一條length(code) = 8 簡稱我必須要先明確code的長度並且還要統一長度,負責就會出現匹配結果變多,還是很尷尬。

2、FIND_IN_SET函式

假如字串str在N子鏈以逗號分割組成的字串列表strlist 中,則返回值的範圍在1到N之間。 如果str不在strlist 或strlist 為空字串,則返回值為0。

關於FIND_IN_SET用法細節我還是不太清楚,有時間再瞭解下。

select b.engine_number,GROUP_CONCAT(code_name) as tran_name

from t_fix_code a,t_inventory_tmp b

where FIND_IN_SET(a.code,b.engine_number) > 0

group by b.engine_number

或者

select b.engine_number,GROUP_CONCAT(code_name) as tran_name

from t_fix_code a

join t_inventory_tmp b ON FIND_IN_SET(a.code,b.engine_number) > 0

group by b.engine_number

 

 

以上是轉自http://blog.csdn.net/wang1988081309/article/details/72920960

重點是GROUP_CONCAT函式和FIND_IN_SET函式

GROUP_CONCAT()函式
GROUP_CONCAT函式返回一個字串結果,該結果由分組中的值連線組合而成。
使用表info作為示例,其中語句SELECT locus,id,journal FROM info WHERE locus IN(‘AB086827′,’AF040764’);的返回結果為
———- —- ————————–
| locus    | id | journal                  |
———- —- ————————–
| AB086827 |  1 | Unpublished              |
| AB086827 |  2 | Submitted (20-JUN-2002)  |
| AF040764 | 23 | Unpublished              |
| AF040764 | 24 | Submitted (31-DEC-1997)  |
———- —- ————————–

1、使用語法及特點:
GROUP_CONCAT([DISTINCT] expr [,expr …]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] [,col …]]
[SEPARATOR str_val])
在 MySQL 中,你可以得到表示式結合體的連結值。通過使用 DISTINCT 可以排除重複值。如果希望對結果中的值進行排序,可以使用 ORDER BY 子句。
SEPARATOR 是一個字串值,它被用於插入到結果值中。預設為一個逗號 (“,”),可以通過指定 SEPARATOR “” 完全地移除這個分隔符。
可以通過變數 group_concat_max_len 設定一個最大的長度。在執行時執行的句法如下: SET [SESSION | GLOBAL] group_concat_max_len = unsigned_integer;
如果最大長度被設定,結果值被剪下到這個最大長度。如果分組的字元過長,可以對系統引數進行設定:SET @@global.group_concat_max_len=40000;

2、使用示例:
語句 SELECT locus,GROUP_CONCAT(id) FROM info WHERE locus IN(‘AB086827′,’AF040764’) GROUP BY locus; 的返回結果為
———- ——————
| locus    | GROUP_CONCAT(id) |
———- ——————
| AB086827 | 1,2              |
| AF040764 | 23,24            |
———- ——————

語句 SELECT locus,GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR ‘_’) FROM info WHERE locus IN(‘AB086827′,’AF040764’) GROUP BY locus;的返回結果為
———- ———————————————————-
| locus    | GROUP_CONCAT(distinct id ORDER BY id DESC SEPARATOR ‘_’) |
———- ———————————————————-
| AB086827 | 2_1                                                      |
| AF040764 | 24_23                                                    |
———- ———————————————————-

語句SELECT locus,GROUP_CONCAT(concat_ws(‘, ‘,id,journal) ORDER BY id DESC SEPARATOR ‘. ‘) FROM info WHERE locus IN(‘AB086827′,’AF040764’) GROUP BY locus;的返回結果為
———- ————————————————————————–
| locus    | GROUP_CONCAT(concat_ws(‘, ‘,id,journal) ORDER BY id DESC SEPARATOR ‘. ‘) |
———- ————————————————————————–
| AB086827 | 2, Submitted (20-JUN-2002). 1, Unpublished                               |
| AF040764 | 24, Submitted (31-DEC-1997) . 23, Unpublished                            |
———- ————————————————————————–

上面的操作只是查詢出來;然後怎麼更新的話可類似如下sql

UPDATE t_bus_type_detail_copy t SET t.fee_type = 
(SELECT x.tran_name FROM
(select b.id,GROUP_CONCAT(a.fee_no) as tran_name
from t_fee_type_config a,t_bus_type_detail_copy b
where FIND_IN_SET(a.fee_type_name,b.fee_type) > 0
group by b.id) x WHERE t.id = x.id);

 


(adsbygoogle = window.adsbygoogle || []).push({});

function googleAdJSAtOnload() {
var element = document.createElement(“script”);
element.src = “//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js”;
element.async = true;
document.body.appendChild(element);
}
if (window.addEventListener) {
window.addEventListener(“load”, googleAdJSAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent(“onload”, googleAdJSAtOnload);
} else {
window.onload = googleAdJSAtOnload;
}