gpt4 book ai didi

php - 一对多链接表导致返回重复行

转载 作者:行者123 更新时间:2023-11-29 05:45:50 24 4
gpt4 key购买 nike

到目前为止,我所看到的一切都是关于自动删除数据库中的重复条目。我想在开头强调,数据库中没有重复数据。我还要从一个事实开始,即我仍在大量学习 RDBMS 设计、规范化、关系,最重要的是 SQL!

我有一个客户表,其中包含一个客户 ID (PK) 和一个客户名称。我有一个角色表,其中包含角色标识 (PK) 和角色名称。任何客户端都可以具有与其关联的多个角色。所以我创建了一个client_role_link表,以clientid和roleid为两个字段。然后我运行这个:

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循环遍历结果并将它们输出到 <select> 中列表。然后导致两个 <option>列出了相同的客户。

我理解为什么我的查询返回两行,这是有道理的。所以这里有两个问题:

  1. 我应该使用更好的数据库/表格设计,还是更优化的查询?
  2. 或者这是我应该在 PHP 中处理的事情吗?如果是这样,是否有更优雅的解决方案,将所有结果添加到一个数组中,然后遍历数组并删除重复项?

想法?

最佳答案

如果你想显示这两个角色,那么你的查询是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 端展开它们,但要确保角色名称不会与分隔符混合。

关于php - 一对多链接表导致返回重复行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2201534/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com