如何让 mysql Group_Concat 使用额外的 CONCAT 信息?
How to get mysql Group_Concat to work with additional CONCAT information?
我正在开发一个 mysql 涉及用户角色 table 的网络应用程序,其中存储了权限级别以及角色 ID 并与用户名及其 ID 相关联(冗余以继续支持遗留代码)。
我希望能够以逗号分隔的简单英语列表形式显示每个用户的角色,同时尽量减少对数据库(> 1k 用户)及其权限级别的影响。
权限存储在 ismanager 和 ishead 列中,roleid 键控到 define_roles (id, rolename)
这是我的作品(但不显示用户级别)
<?
$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>";
}
?>
输出:
- 测试用户销售
- UserTest2 销售、收发室、门卫
我想看的是
- 测试用户销售(经理)
- UserTest2 销售、收发室(负责人)、门卫(经理)
我能想到的最好的(虽然它不起作用)是:
$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)
首先,您可能应该规范化您的数据库,以便您有一个单独的 table 链接用户和定义的角色。但那是另一回事,我很感激你可能无法做到这一点。
如果我正确理解了您 table 中的内容,我认为答案是:
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;
您不需要初始的 sql,您从 define_roles 中查找角色名称。
[编辑]:抱歉,更新了内部 SELECT 周围的括号。
我正在开发一个 mysql 涉及用户角色 table 的网络应用程序,其中存储了权限级别以及角色 ID 并与用户名及其 ID 相关联(冗余以继续支持遗留代码)。
我希望能够以逗号分隔的简单英语列表形式显示每个用户的角色,同时尽量减少对数据库(> 1k 用户)及其权限级别的影响。
权限存储在 ismanager 和 ishead 列中,roleid 键控到 define_roles (id, rolename)
这是我的作品(但不显示用户级别)
<?
$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>";
}
?>
输出:
- 测试用户销售
- UserTest2 销售、收发室、门卫
我想看的是
- 测试用户销售(经理)
- UserTest2 销售、收发室(负责人)、门卫(经理)
我能想到的最好的(虽然它不起作用)是:
$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)
首先,您可能应该规范化您的数据库,以便您有一个单独的 table 链接用户和定义的角色。但那是另一回事,我很感激你可能无法做到这一点。
如果我正确理解了您 table 中的内容,我认为答案是:
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;
您不需要初始的 sql,您从 define_roles 中查找角色名称。
[编辑]:抱歉,更新了内部 SELECT 周围的括号。