在MySQL中拆分id的csv字符串以引用子查询

时间:2011-10-06 14:37:53

标签: mysql

以下查询将返回与给定文档关联的ID,与文档关联的人类可读权限列表,包含组ID,角色以及在文档中分配给它们的权限的用户的字符串(我知道这种分配权限的方法是垃圾,唉,这就是我所掌握的),以及每个人是否都可以通过REGEXP检查进行访问。 1 =是的,每个人都应该有权访问该文档,0 =不是每个人。

SELECT
    `D`.`id` AS `docID`,
    `P`.`human_name` AS `permissionName`,
    `PD`.`descriptor_text` AS `permissionAssignments`,
    `PD`.`descriptor_text` REGEXP '.*role\\((-4,)?-3.*' AS `everyoneAccess`
FROM `documents` AS `D`
INNER JOIN `permission_lookups`            AS `PL`  ON `D`.`permission_lookup_id` = `PL`.`id`
INNER JOIN `permission_lookup_assignments` AS `PLA` ON `PL`.`id` = `PLA`.`permission_lookup_id`
INNER JOIN `permission_descriptors`        AS `PD`  ON `PLA`.`permission_descriptor_id` = `PD`.`id`
LEFT JOIN `permission_descriptor_roles`    AS `PDR` ON `PDR`.`descriptor_id` = `PD`.`id`
LEFT JOIN `permissions`                    AS `P`   ON `PLA`.`permission_id` = `P`.`id`
WHERE `D`.`id` = 74;

此特定查询的输出类似于:

74  Read            group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389) 1
74  Write           group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294)           0
74  Add Folder  group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294)           0
74  Manage security group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294)           0
74  Delete          group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294)           0
74  Manage workflow group(1)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294)           0
74  Folder Details  group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389) 1
74  Rename Folder   group(1)                                                                                    0

在第3列,第一行(例如)下,字符串:group(1)role(-3)user(13,14,26,38,56,73,81,88,103,108,138,140,148,158,159,175,191,276,294,15389)表示ID为1的组可以访问读取权限,ID为-3的角色具有访问权限(-3表示所有人)对于读取许可,并且具有不同的角色分配等,在解决状态下,具有ID 13,14,26,38,56,73,81,88,103,108,138,140,​​148,158,159,175,191,276,294,15389的用户可以访问。因此,在这种情况下,由于文档具有分配给它的每个人角色,每个人都有访问权限,但是他们还对长串用户进行了特定访问,作为跨越所有权限的一揽子。

我想要做的是拔出csv用户列表,并在子查询中使用它来在同一查询中提取他们的用户名。我尝试以下查询,但没有任何运气,它只返回csv列表中的第一个用户:

SELECT
    `D`.`id` AS `docID`,
    `P`.`human_name` AS `permissionName`,
    `PD`.`descriptor_text` AS `permissionAssignments`,
    `PD`.`descriptor_text` REGEXP '.*role\\((-4,)?-3.*' AS `everyoneAccess`,
        IF(`PD`.`descriptor_text` REGEXP '.*user\\([0-9,]+)$',
            (SELECT group_concat(`username`) FROM users where `id` IN 
                (
                    SUBSTR(
                        `PD`.`descriptor_text`,
                        INSTR(`PD`.`descriptor_text`, 'user(') + 5,
                        LENGTH(`PD`.`descriptor_text`) - INSTR(`PD`.`descriptor_text`, 'user(') - 5
                    )
                )
            ),
            NULL
        )
FROM `documents` AS `D`
INNER JOIN `permission_lookups`            AS `PL`  ON `D`.`permission_lookup_id` = `PL`.`id`
INNER JOIN `permission_lookup_assignments` AS `PLA` ON `PL`.`id` = `PLA`.`permission_lookup_id`
INNER JOIN `permission_descriptors`        AS `PD`  ON `PLA`.`permission_descriptor_id` = `PD`.`id`
LEFT JOIN `permission_descriptor_roles`    AS `PDR` ON `PDR`.`descriptor_id` = `PD`.`id`
LEFT JOIN `permissions`                    AS `P`   ON `PLA`.`permission_id` = `P`.`id`
WHERE `D`.`id` = 74;

在第4个字段中可以更改什么来让它根据id的csv查询用户名的group_concat列表?

1 个答案:

答案 0 :(得分:1)

不能保证这将是快速,但我相信它可以解决您的问题。

SELECT
    `D`.`id` AS `docID`,
    `P`.`human_name` AS `permissionName`,
    `PD`.`descriptor_text` AS `permissionAssignments`,
    `PD`.`descriptor_text` REGEXP '.*role\\((-4,)?-3.*' AS `everyoneAccess`,
    IF(`PD`.`descriptor_text` REGEXP '.*user\\([0-9,]+)$',
        (SELECT group_concat(`username`) FROM users where `PD`.`descriptor_text`
            REGEXP CONCAT('user[(0-9,]*[(,]', `id`, '[\),]')
        ),
        NULL
    )
FROM `documents` AS `D`
INNER JOIN `permission_lookups`            AS `PL`  ON `D`.`permission_lookup_id` = `PL`.`id`
INNER JOIN `permission_lookup_assignments` AS `PLA` ON `PL`.`id` = `PLA`.`permission_lookup_id`
INNER JOIN `permission_descriptors`        AS `PD`  ON `PLA`.`permission_descriptor_id` = `PD`.`id`
LEFT JOIN `permission_descriptor_roles`    AS `PDR` ON `PDR`.`descriptor_id` = `PD`.`id`
LEFT JOIN `permissions`                    AS `P`   ON `PLA`.`permission_id` = `P`.`id`
WHERE `D`.`id` = 74;

不是试图分解字符串,而是使用精心构造的正则表达式在字符串中搜索id。