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

问题描述 投票:0回答:2

用户表:

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子句,则会出现所有SetNames;但如果我指定了所需的ID,我只会获得与第一个ID相关联的名称。显然,我还需要以与ID相同的顺序获取SetNames。因此在GROUP_CONCAT中有ORDER BY。

也:

  • 有没有更好的方法(除了将用户指令集分配存储在单独的表中 - 对于此应用程序来说是否过度杀伤)?在这种情况下无法看到如何使用JOIN。
  • 这个问题有更好的标题吗?

谢谢。

mysql group-concat
2个回答
1
投票

而不是像这样使用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
投票

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

我们也可以在FIND_IN_SET()条款中使用WHERE。 (当在字符串列表中找不到字符串时,函数返回0。)

EG

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 
© www.soinside.com 2019 - 2024. All rights reserved.