用户表:
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。
也:
谢谢。
答案 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
存储用逗号分隔的列表是一种反模式;单独的桌子并不过分。
假设id
在Users
表中是唯一的,我们可以对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