2015-05-06 24 views
1

我目前2個表看起來像這樣:Mysql的分割字符串,並選擇與結果

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 

我試圖拆用戶組,併爲每個編號選擇的用戶組,並將其添加顯示的結果應該看起來像是最好的情況:

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

最好的結果我f到目前爲止是從這裏: Split String and Do Calculation in MySQL 但我似乎無法從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結果?

+1

壞DB設計檢查,你應該正常化它,不會保存逗號分隔的數據關係屬性。 –

+0

它失敗**第一個正常形式** – Premraj

+0

可悲的是我不能改變這一點,因爲它是預定義的,並在整個cms中使用。 – StifanCral

回答

1

你應該考慮正常化。然而,對於目前的架構考慮以下

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    | 
+------+---------+-----------------------+ 

期望的結果現在更好的方法是創建一個協會表作爲

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    | 
+------+---------+-----------------------+ 
+0

非常感謝,它的工作完美,也非常感謝標準化的建議 – StifanCral

0

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