Mysql

Group_concat 加入多個表

  • August 27, 2021

我有以下方案

users:        researches:                  researchyear:

uid | name    rid| titleAr                  rid     |  uid     | 
---+--------  ---+------------              --------+----------+
1 | Peter     1 | Tennis                         1 |        1 |
2 | Alice     2 | Football                       1 |        2 | 
3 | Bob       3 | Basketball                     2 |        3 | 
                                                 3 |        1 |
                                                 3 |        3 | 
                                                 3 |        2 |

我想通過特定的 researcher_Id(uid) 與它的研究人員(使用者)進行研究,即當我設置使用者 ID(1,3 或 2)時,我想得到相同的結果。

id |titleAr    | users_ids | users_names
---+-------+-----------+----------------------------
3 |Basketball | 1,3,2     | Peter,Bob,Alice

我嘗試了以下查詢,我可以在其中獲得研究人員(使用者)的每項研究:

SELECT r.rId,
      r.titleAr,
      Group_concat(u.userId ) users_ids ,
     Group_concat(u.name )      users_names
FROM   research r
          LEFT JOIN researchyear ry
                    ON r.rId = ry.rId
          LEFT  JOIN users u
                     ON ry.uId = u.userId
GROUP  BY r.rId, r.titleAr

如何為一位使用者獲取它?

如果你想列出所有users的名字,包括uid你想把它放在你的 where 子句中:

WHERE EXISTS(SELECT * FROM researchyear t WHERE t.rid = r.id AND t.uid = {your_uid} )

另一種選擇是應用行組過濾器,即使用HAVING子句。如果您只想允許包含特定使用者/研究人員的組,您可以在條件計數的幫助下做到這一點:

SELECT r.rId,
      r.titleAr,
      Group_concat(u.userId ) users_ids ,
      Group_concat(u.name )      users_names
FROM   research r
          LEFT JOIN researchyear ry
                    ON r.rId = ry.rId
          LEFT  JOIN users u
                     ON ry.uId = u.userId
GROUP  BY r.rId, r.titleAr
HAVING COUNT(CASE u.userId /* or: r.uid */ WHEN @specific_user_id THEN 1 END) > 0 ;

請注意,條件計數在 MySQL 中可以有各種實現。最短的(如果不是最短的)之一是 using SUM,所以在你的情況下它會是

...
HAVING SUM(u.userId = @specific_user_id) > 0 ;
/* or: SUM(r.uid = @specific_user_id) > 0 */

EXISTS之前建議的方法不同,這避免了多次訪問基礎表,這可能會帶來更好的性能,儘管在小型數據集上,改進(如果有的話)可能可以忽略不計。

引用自:https://dba.stackexchange.com/questions/298517