Multi-row Merge and Single-Row Split for String Operation of MySQL Query Result Set

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_concatthis 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_concatas 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_concatthe 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_indexthe 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

Guess you like

Origin blog.csdn.net/u011738045/article/details/120334688