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
我目前有 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
到目前为止我找到的最好结果来自这里:
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