基于指定值的子查询中的GROUP_CONCAT

时间:2019-04-22 21:16:48

标签: mysql group-concat

用户表:

ID       InstructionSets
 1        123,124

指令集表:

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

如预期的那样,如果我在子查询中删除了WHERE子句,则所有SetName都会出现。但是如果指定了所需的ID,则只会得到与第一个ID相关联的名称。显然,我还需要以与ID相同的顺序来获取SetName。因此,在GROUP_CONCAT中使用ORDER BY。

也:

  • 是否有更好的方法(除了将用户指令集分配存储在单独的表中之外–对于该应用程序来说是过大的做法)?在此看不到如何使用JOIN 情况。
  • 这个问题有更好的标题吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

代替IN那样使用LIKE运算符:

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 |

答案 1 :(得分:1)

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

我们还可以在FIND_IN_SET()子句中使用WHERE。 (当在字符串列表中找不到该字符串时,函数将返回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

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


假设idUsers表中是唯一的,我们可以对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