前言
我們在做項目寫sql語句的時候,是否會遇到這樣的場景,就是需要把查詢出來的多列,按照字符串分割合並成一列顯示,或者把存在數據庫里面用逗號分隔的一列,查詢分成多列呢,常見場景有,文章標簽,需要吧查詢多個標簽合並成一列,等,需要怎么去實現呢,這就涉及到MySQL的字符串
操作
group_concat
場景再現 我想把查詢多列數據合並成一列顯示用逗號分隔就需要用到
group_concat
這個函數
下面sql語句
select r.ROLE_NAME
from t_user u
right join t_user_role ur on ur.USER_ID = u.USER_ID,
t_role r
where r.ROLE_ID = ur.ROLE_ID
and u.USER_ID = 7
ID為7的用戶有兩個角色,但是我現在想把它顯示成一列,就需要用到字符串函數group_concat
如下sql
select group_concat(r.ROLE_NAME)
from t_user u
right join t_user_role ur on ur.USER_ID = u.USER_ID,
t_role r
where r.ROLE_ID = ur.ROLE_ID
and u.USER_ID = 7;
實現了我需要的功能
當然
group_concat
函數默認使用逗號,進行連接,我們也可以自己指定分隔連擊符如group_concat(name separator ';')
select group_concat(r.ROLE_NAME separator ';')
from t_user u
right join t_user_role ur on ur.USER_ID = u.USER_ID,
t_role r
where r.ROLE_ID = ur.ROLE_ID
and u.USER_ID = 7;
當然實際應用不單單這么簡單,需要結合子查詢使用,
如下sql 查詢用戶詳細信息,就包括用戶角色信息
,部門信息
等
select tu.*,
d.DEPT_NAME,
(select group_concat(r.ROLE_NAME)
from t_user u
left join t_user_role ur on ur.USER_ID = u.USER_ID,
t_role r
where r.ROLE_ID = ur.ROLE_ID
and u.USER_ID = tu.USER_ID) as roles
from t_user tu
left join
t_dept d
on tu.DEPT_ID = d.DEPT_ID
where tu.USER_ID=7;
substring_index(str,delim,count)
場景在現某些業務表出於歷史原因或性能原因,都使用了違反
第一范式
的設計模式。即同一個列中存儲了多個屬性值。如下表中的 theme 所示:
這種情況下,可以考慮將該列根據分隔符進行分割,形成多個列就需要使用到substring_index
函數
SUBSTRING_INDEX(str,delim,count)
-- str: 被分割的字符串; delim: 分隔符; count: 分割符出現的次數
對於字符串 “1,2,3” ,設置delim為 “,”,count為1,就會返回 “1”;其它參數不變,count為2,就會返回 “1,2”;其它參數不變,count為-1,就會返回 “3”。
如下sql
select USERNAME,
(select substring_index(tu.THEME, ',', 1) from t_user tu where tu.USER_ID = 1) theme1,
(select substring_index(tu.THEME, ',', 2) from t_user tu where tu.USER_ID = 1) theme2,
(select substring_index(tu.THEME, ',', -1) from t_user tu where tu.USER_ID = 1) theme3
from t_user
where USER_ID = 1;
顯然不符合我們所需要的,我們可以在嵌套sql自查詢實現如下
select USERNAME,
(select substring_index(tu.THEME, ',', 1) from t_user tu where tu.USER_ID = 1) theme1,
(select substring_index((select substring_index(tu.THEME, ',', 2) from t_user tu where tu.USER_ID = 1),',',-1) theme2),
(select substring_index(tu.THEME, ',', -1) from t_user tu where tu.USER_ID = 1) theme3
from t_user
where USER_ID = 1;
當然這個計算應該是動態的可以參考參考實現