Mysql 拆分字符串和 Select 结果

Mysql Split String and Select with results

我目前有 2 个 table 看起来像这样:

frontend_users:
uid | usergroup | name
1   | 1,2,3     | Michael
2   | 2         | Tobias
3   | 1         | Colin
...

usergroups:
uid | title
1   | member
2   | reporter
3   | admin

我尝试拆分用户组和 select 用户组的每个数字并将其添加到显示结果中,在最佳情况下应该如下所示:

uid | name    | groups
1   | Michael | member, reporter, admin
2   | Tobias  | reporter
3   | Colin   | member

到目前为止我找到的最好结果来自这里: 但我似乎无法从另一个 table select 得到 substring_index 结果。 我当前的查询如下所示:

SELECT frontend_users.uid, frontend_users.name
CASE
    WHEN frontend_users.usergroup LIKE '%,%,%' THEN
        CONCAT((SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = SUBSTRING_INDEX(frontend_users.usergroup, ',', 1)),
            (SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(frontend_users.usergroup, ',', 2), ',', -1)),
            (SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(frontend_users.usergroup, ',', 3), ',', -1)))       
    WHEN frontend_users.usergroup LIKE '%,%' THEN
        CONCAT((SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = SUBSTRING_INDEX(frontend_users.usergroup, ',', 1)),
            (SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(frontend_users.usergroup, ',', 2), ',', -1))),
    ELSE (SELECT usergroups.title FROM usergroups, frontend_users WHERE usergroups.uid = frontend_users.usergroup)
END AS groups
FROM frontend_users, usergroups

我尝试对组数使用 for 循环,但结果更糟。

关于如何使用 select 查询和 substring_index 结果的任何提示?

你应该考虑标准化。但是,对于当前架构,请考虑以下内容

mysql> select * from frontend_users ;
+------+-----------+---------+
| uid  | usergroup | name    |
+------+-----------+---------+
|    1 | 1,2,3     | Michael |
|    2 | 2         | Tobias  |
|    3 | 1         | Colin   |
+------+-----------+---------+
3 rows in set (0.00 sec)

mysql> select * from usergroup ;
+------+----------+
| uid  | title    |
+------+----------+
|    1 | member   |
|    2 | reporter |
|    3 | admin    |
+------+----------+
3 rows in set (0.00 sec)

要获得所需的结果,您可以使用以下查询,该查询在很长时间内效率不高 运行

select 
u.uid,
u.name, 
group_concat(g.title) as groups 
from frontend_users u 
join usergroup g on find_in_set(g.uid,u.usergroup) > 0 
group by u.uid ;

+------+---------+-----------------------+
| uid  | name    | groups                |
+------+---------+-----------------------+
|    1 | Michael | admin,reporter,member |
|    2 | Tobias  | reporter              |
|    3 | Colin   | member                |
+------+---------+-----------------------+

现在更好的方法是创建关联 table as

mysql> create table user_to_group (uid int, gid int);
Query OK, 0 rows affected (0.15 sec)

mysql> insert into user_to_group values (1,1),(1,2),(1,3),(2,2),(3,1);
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

更好的查询是

select 
u.uid,
u.name, 
group_concat(g.title) as groups 
from frontend_users u 
join user_to_group ug on ug.uid = u.uid 
join usergroup g on g.uid = ug.gid 
group by u.uid ;

+------+---------+-----------------------+
| uid  | name    | groups                |
+------+---------+-----------------------+
|    1 | Michael | member,admin,reporter |
|    2 | Tobias  | reporter              |
|    3 | Colin   | member                |
+------+---------+-----------------------+

Abhik Chakraborty 的回答是更好的解决方案,但如果您愿意,我只是修复了您最后的代码。

您可以在fiddle

查看
SELECT frontend_users.uid, frontend_users.name,
CASE
    WHEN usergroup LIKE '%,%,%' THEN
        CONCAT(
           (
             SELECT title FROM usergroups
             WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(usergroup, ',', 1), ',', -1)
           )
          ,',',
           (
              SELECT title FROM usergroups
              WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(usergroup, ',', 2), ',', -1)
            )
          ,',',
           (
              SELECT title FROM usergroups
              WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(usergroup, ',', 3), ',', -1)
            )
          )
    WHEN usergroup LIKE '%,%' THEN
        CONCAT(
           (
             SELECT title FROM usergroups
             WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(usergroup, ',', 1), ',', -1)
           )
          ,',',
           (
              SELECT title FROM usergroups, frontend_users
              WHERE usergroups.uid = SUBSTRING_INDEX(SUBSTRING_INDEX(usergroup, ',', 2), ',', -1) Limit 1
            )
          )
    ELSE
        (SELECT title FROM usergroups, frontend_users WHERE usergroups.uid = usergroup Limit 1)
END AS groups
FROM frontend_users