MySQL - GROUP_CONCAT 如果值不是子字符串

MySQL - GROUP_CONCAT if value is not a substring

我的 table 中有一个名为 "Permissions" 的专栏。权限是字符串,可以是: "r","w","x","rw","wx","rwx","xwr" 等等 请注意字符串中字符的顺序是不固定的。我想在 table 的 "Permissions" 列上 GROUP_CONCAT()。然而,这会导致非常大的字符串。

示例:"r","wr","wx" 串联的组是 "r,wr,wx",但应该是 "r,w,x""rwx"。使用 distinct() 子句似乎没有多大帮助。我在想,如果我可以检查一个权限值是否是另一列的子字符串,那么我不应该连接它,但我似乎没有找到实现它的方法。

任何仅使用字符串函数的基于列的方法也适用。

编辑: 这是一些示例数据:

+---------+
| perm    |
+---------+
| r,x,x,r |
| x       |
| w,rw    |
| rw      |
| rw      |
| x       |
| w       |
| x,x,r   |
| r,x     |
+---------+

拼接后的结果应该是:

 +---------+
 | perm    |
 +---------+
 | r,w,x   |
 +---------+

我无法控制数据源并且不想创建新的 tables(因为权限和内存限制)。我正在寻找一个 post 处理步骤,将每个列值转换为所需的格式。

一个好主意是首先标准化你的数据。

例如,您可以尝试这种方式(我假设您的来源 table 被命名为 Files):

  1. 创建名为 PermissionCodes 的简单 table,只有名为 Code 的列(字符串类型)。

  2. rwx 作为值放入 PermissionCodes(总共三行)。

  3. 在子查询中将 Files 连接到 PermissionCodes,条件是 Code 作为子字符串存在于 Permissions.

  4. 对子查询的结果执行 GROUP_CONCAT 聚合。

如果是这种情况,对于 Files 中相同的逻辑整体,存在多个重叠的权限集(即对于某些文件,有一行 rw 和另一行w) 那么您会将子查询限制为 distinct Files' 键和 Code.

的组合

这里有一个 fiddle 来证明这个想法:

http://sqlfiddle.com/#!9/6685d6/4

您可以尝试类似的方法:

SELECT user_id, GROUP_CONCAT(DISTINCT perm)
FROM Permissions AS p
INNER JOIN (SELECT 'r' AS perm UNION ALL 
            SELECT 'w' UNION ALL
            SELECT 'x') AS x
ON p.permission LIKE CONCAT('%', x.perm, '%')
GROUP BY user_id

您可以在派生的 table 的 UNION ALL 中包含任何额外的权限代码,用于 JOIN with Permissions table.

Demo here