foreword
When we write sql statements in a project, will we encounter such a scenario, that is, we need to divide and merge multiple columns from the query into one column for display according to the string, or divide the query into multiple columns separated by commas in the database Columns, common scenarios include article tags, you need to query multiple tags and merge them into one column, etc., how to achieve it, which involves the operation of 字符串
MySQL
group_concat
Scene reproduction I want to combine multiple columns of query data into one column and display them separated by commas, so I need to use
group_concat
this function
The following sql statement
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
The user with ID 7 has two roles, but now I want to display it as a column, I need to use the string function group_concat
as follows 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;
Achieved what I needed
Of course,
group_concat
the function uses commas by default to connect, and we can also specify the delimiting combo by ourselves, such asgroup_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;
Of course, the actual application is not only so simple, it needs to be used in combination with subqueries.
The following sql queries user details, including users 角色信息
, 部门信息
etc.
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)
The scenario is that some business tables use a violated
第一范式
design pattern for historical reasons or performance reasons. That is, multiple attribute values are stored in the same column. As shown in the theme in the table below:
In this case, you can consider splitting the column according to the delimiter. To form multiple columns, you need to use substring_index
the function
SUBSTRING_INDEX(str,delim,count)
-- str: 被分割的字符串; delim: 分隔符; count: 分割符出现的次数
For the string "1,2,3", set delim to "," and count to 1, it will return "1"; other parameters remain unchanged, if count is 2, it will return "1,2"; other parameters are not Change, count is -1, it will return "3".
The following 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;
Obviously it does not meet our needs, we can implement the nested sql self-query as follows
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;
Of course, this calculation should be dynamic, you can refer to the reference implementation