如何让 mysql Group_Concat使用其他 CONCAT 信息


How to get mysql Group_Concat to work with additional CONCAT information?

我正在开发一个带有mysql的Web应用程序,该应用程序涉及一个用户角色表,其中存储了权限级别以及角色ID,并与用户名及其ID相关联(冗余以继续支持遗留代码)。

我希望能够以简单的英语将每个用户的角色显示为逗号分隔列表,同时对数据库(>1k 用户)及其权限级别的打击最小。

权限以位的形式存储在 ismanager 和 ishead 列中,角色 ID 键控define_roles(id、角色名)

这是我的作品(但不显示用户级别)

<?
$rolenames = array();
foreach($db->query("SELECT id, rolename FROM define_roles") as $row)
{
    $rolenames[$row['id']] = $row['rolename'];
}
foreach($db->query("SELECT DISTINCT userid, username, 
                        GROUP_CONCAT(DISTINCT roleid  ORDER BY roleid) AS idlist
                        FROM user_roles 
                        GROUP BY userid 
                        ORDER BY username ASC") as $row)
{
    $rolestring = '';
    //echo $row['idlist'];
    foreach(explode(',',$row['idlist']) as $id)
    {
        $rolestring .= " ".$rolenames[$id].",";
    }
    $rolestring = rtrim($rolestring,',');
    echo "<tbody>
            <tr>
                <td><font size='1'>" . $row['username'] . "</font></td>
                <td><font size='1'>" .$rolestring. "</font></td>
            </tr>";
}
?>

输出:

  • 测试用户销售
  • 用户测试2 销售、邮件收发室、清洁

我想看到的是

  • 测试用户销售(经理)
  • 用户测试2 销售、收发室(主管)、清洁(经理)

我能想到的最好的(尽管它不起作用)是:

$rolenames = array();
foreach($db->query("SELECT id, rolename FROM define_roles") as $row)
{
    $rolenames[$row['id']] = $row['rolename'];
    $rolenames[$row['id']."10"] = $row['rolename']." (Manager)";
    $rolenames[$row['id']."01"] = $row['rolename']." (Head)";
    $rolenames[$row['id']."11"] = $row['rolename']." (Head)";
}
foreach($db->query("SELECT DISTINCT userid, username, 
                        GROUP_CONCAT
                        (
                            CONCAT(roleid,ismanager,ishead) ORDER BY roleid
                        ) AS idlist
                        FROM user_roles 
                        GROUP BY userid 
                        ORDER BY username ASC") as $row)

首先,您可能应该规范化数据库,以便有一个单独的表链接用户和定义的角色。 但那是另一回事,我很感激你可能无法做到这一点。

如果我正确理解了您表格中的内容,答案是这样的,我认为:

SELECT 
    userid, 
    username, 
    GROUP_CONCAT(DISTINCT 
        CONCAT(
            (SELECT d.rolename FROM define_roles AS d
            WHERE d.id = roleid)
        ), 
        IF(ismanager = 1, " (Manager)", ""),
        IF(ishead = 1, " (Head)", "")
    ) AS roles
FROM user_roles
GROUP BY userid;

您不需要从define_roles中查找角色名称的初始 sql。

[编辑]:抱歉,更新了内部选择周围的括号。