Php 导致返回重复行的一对多链接表
到目前为止,我所看到的一切都是关于自动删除数据库中的重复条目。我想在开始时强调,数据库中没有重复数据。我还将从以下事实开始:我仍然在学习RDBMS设计、规范化、关系,最重要的是SQL 我有一个客户表,有一个clientid(PK)和一个client_名称。我有一个角色表,有一个roleid(PK)和一个role_名称。任何客户端都可以有多个与其关联的角色。因此,我创建了一个client_role_link表,其中clientid和roleid是两个字段。然后我运行这个:Php 导致返回重复行的一对多链接表,php,mysql,relationship,Php,Mysql,Relationship,到目前为止,我所看到的一切都是关于自动删除数据库中的重复条目。我想在开始时强调,数据库中没有重复数据。我还将从以下事实开始:我仍然在学习RDBMS设计、规范化、关系,最重要的是SQL 我有一个客户表,有一个clientid(PK)和一个client_名称。我有一个角色表,有一个roleid(PK)和一个role_名称。任何客户端都可以有多个与其关联的角色。因此,我创建了一个client_role_link表,其中clientid和roleid是两个字段。然后我运行这个: SELECT clien
SELECT client.client_name, role.role_name FROM client
LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid
LEFT JOIN role ON client_role_link.roleid=role.roleid
WHERE (role.roleid='1' OR role.roleid='2')
假设我有一个客户机,它有两个关联的角色(角色“1”和“2”)。此查询返回两行,每个角色一行。当我得到这些结果时,我使用while
循环遍历结果并将它们输出到
列表中。然后,它会对列出的同一个客户端导致两个
我理解为什么我的查询返回两行,这是有道理的。所以这里有两个问题:
想法?如果您想同时显示这两个角色,那么您的查询是
OK
MySQL
不支持数组数据类型,因此您应该在PHP
端使用重复的客户端名称填充关联数组
如果您只需要显示具有任一角色的客户端,请使用以下查询:
SELECT c.*
FROM client c
WHERE c.clientid IN
(
SELECT roleid
FROM client_role_link crl
WHERE crl.roleid IN (1, 2)
)
这将为每个客户端返回一条记录,但不会显示任何角色
第三种方法将使服务器端的角色名称内爆:
SELECT c.*, GROUP_CONCAT(role_name SEPARATOR ';') AS roles
FROM client c
LEFT JOIN
client_role_link crl
ON crl.clientid = c.clientid
AND crl.roleid IN (1, 2)
LEFT JOIN
role r
ON r.roleid = crl.roleid
GROUP BY
c.id
并在PHP的端分解它们,但要确保角色名不会与分隔符混合。您可以使用它们以数组形式返回。然后,您可以有一些未经测试的代码,但可以工作:
你们到底想用它来完成什么?您想输出所有客户端的列表还是所有角色的列表?还是别的什么?我只想显示具有特定角色的客户机,并让它们可以选择。在这个特殊的例子中,我实际上不需要拉角色名。我认为第一个例子更符合我的要求,但我对“in”不太熟悉,所以我必须查一下。我假设您只是针对生成的数据集运行SQL?是的,我知道MySQL没有数组,我正在使用mysqli和fetch_assoc()方法将我的数据从结果集中获取到PHP数组中。我只是不想在生成的数组中循环并删除重复项!这部分是我试图避免的,但比我提出的解决方案要干净得多。
$sql = "SELECT client.id, client.client_name, role.role_name FROM client LEFT JOIN client_role_link ON client_role_link.clientid=client.clientid LEFT JOIN role ON client_role_link.roleid=role.roleid WHERE (role.roleid='1' OR role.roleid='2')";
$result = mysql_query($sql);
$res = array();
while ($row = mysql_fetch_assoc($result)) {
$res[$row['id']]['roles'][] = $row['role_name'];
$res[$row['id']]['client_name'] = $row['client_name']; //you'll be overwriting each iteration probably a better way
}