GROUP_CONCAT in sub-query 基于指定值

GROUP_CONCAT in sub-query based on specified values

用户Table:

ID       InstructionSets
 1        123,124

指令集Table:

ID       Name
 123      Learning SQL
 124      Learning More SQL  

想要的查询结果:

UserID    SetID             SetNames
 1         123,124           Learning SQL,Learning More SQL

当前SQL:

SELECT U1.ID AS UserID, U1.InstructionSets AS SetID, (
    SELECT GROUP_CONCAT(Name ORDER BY FIELD(I1.ID, U1.InstructionSets))
    FROM Instructions I1
    WHERE I1.ID IN (U1.InstructionSets)
) AS SetName
FROM Users U1
WHERE `ID` = 1

结果

UserID   SetID             SetNames
 1        123,124           Learning SQL

正如预期的那样,如果我删除 sub-query 中的 WHERE 子句,所有的 SetNames 都会出现;但是如果我指定所需的 ID,我只会得到与第一个 ID 关联的名称。显然,我还需要按照与 ID 相同的顺序获取 SetNames。因此 ORDER BY 在 GROUP_CONCAT.

另外:

谢谢。

像这样使用 LIKE 运算符而不是 IN:

SELECT U1.ID AS UserID, U1.InstructionSets AS SetID, (
    SELECT GROUP_CONCAT(Name ORDER BY (I1.ID))
    FROM Instructions I1
    WHERE CONCAT(',', U1.InstructionSets, ',') LIKE concat('%,', I1.ID, ',%')
) AS SetName
FROM Users U1
WHERE `ID` = 1

参见demo
结果:

| UserID | SetID   | SetName                        |
| ------ | ------- | ------------------------------ |
| 1      | 123,124 | Learning SQL,Learning More SQL |

我们可以使用FIND_IN_SET()。在这种情况下,使用 FIELD() 函数没有意义。

我们也可以在WHERE子句中使用FIND_IN_SET()。 (当在字符串列表中找不到该字符串时,函数 returns 0。)

例如

SELECT u.id               AS userid
     , u.instructionsets  AS setid
     , ( SELECT GROUP_CONCAT(i.name ORDER BY FIND_IN_SET(i.id, u.instructionsets))
           FROM `Instructions` i
          WHERE FIND_IN_SET(i.id, u.instructionsets))
       ) AS setname
 FROM `Users` u
WHERE u.id = 1

存储逗号分隔列表是一种反模式;一个单独的 table 并不过分。


假设 idUsers table 中是唯一的,我们可以使用 GROUP BY

进行连接操作
SELECT u.id                   AS userid
     , MIN(u.instructionsets) AS setid
     , GROUP_CONCAT(i.name ORDER BY FIND_IN_SET(i.id, u.instructionsets))) AS setname
 FROM `Users` u
 LEFT
 JOIN `Instructions` i
   ON FIND_IN_SET(i.id, u.instructionsets)
WHERE u.id = 1
GROUP BY u.id