【发布时间】:2018-02-08 12:26:12
【问题描述】:
我有 3 个表,一个 client 表,一个 user 表和一个 user_has_client 表。
user_has_client 表用于加入其他 2 个表,但它也有一个 roles 列。
MariaDB [extrapack]> desc user;
+----------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------------------+------+-----+---------+----------------+
| user_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(255) | NO | UNI | NULL | |
MariaDB [extrapack]> desc client;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| client_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
MariaDB [extrapack]> desc user_has_client;
+-----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| user_id | int(10) unsigned | NO | PRI | NULL | |
| client_id | int(10) unsigned | NO | PRI | NULL | |
| roles | tinytext | YES | | NULL | |
+-----------+------------------+------+-----+---------+-------+
client 和user 可能有多个不同的roles,roles 列是一个数组。
MariaDB [extrapack]> select * from user_has_client where roles != "" limit 3;
+---------+-----------+---------+
| user_id | client_id | roles |
+---------+-----------+---------+
| 181 | 395 | cpa, ce |
| 181 | 473 | cpa |
| 181 | 498 | cpa |
+---------+-----------+---------+
但是一个客户只能为一个用户提供一个相同的角色。例如,同一客户端上不能有两个不同的用户拥有cpa 角色。
我想列出一个客户,对于该客户,如果有这样的用户,则只列出一个具有cpa 角色的用户。
这是我的声明:
SELECT c.client_id AS client_id0, ou.user_id AS user_id3, ou.email AS email5 FROM client c LEFT JOIN user_has_client ouhc ON c.client_id = ouhc.client_id LEFT JOIN user ou ON ouhc.user_id = ou.user_id AND ouhc.roles LIKE '%cpa%' WHERE c.client_id = 265 ORDER BY ou.email DESC;
client 和 user 可能有也可能没有加入记录,但即便如此,我仍然想显示client 的列表行,所以我无法进行内部连接并拥有进行左连接。
但是在进行左连接时,我仍然希望每个客户端只有一个列表行。
截至目前,上述语句为我提供了客户端的n 行,因为n 用户已加入此客户端。但是这些n 用户中只有一个在其加入中具有cpa 角色。所以我只想显示一个列表行,并与该用户一起显示。
所以,总而言之,我总是希望每个客户端一行,并且只需要一行,并且对于给定角色的用户来说,如果该客户端有 cpa 角色的话。
【问题讨论】:
-
唯一索引是在用户 ID - 角色字段还是客户端 ID - 角色组合上,问题并不完全清楚。
But one client can offer only one same role to one user. For example, there cannot be one same user having the cpa role on two different clients.引用的句子不清楚,示例不适用于引用的第1句。 -
引用的第二句确实是错误的。我的错。我将在问题中纠正它。它应该是
For example, there cannot be two different users having the cpa role on one same client. -
我改写了问题标题,以便更好地关注实际问题。
-
如果左连接是这里的主要问题,那么这个问题是重复的。
-
@Shadow 从问题的 MySQL 语句中可以看出,我已经应用了现有重复问题中显示的相同解决方案,即在 @ 后面加上
AND的子句加入的987654346@:LEFT JOIN user ou ON ouhc.user_id = ou.user_id AND ouhc.roles LIKE '%cpa%'。但是当我需要它只显示一个时它仍然显示很多行。在旁注中,我认为现有的重复问题具有误导性,因为应用了位于ON子句中的WHERE子句,而不是before,但仅适用于与联接匹配的那些记录,而不是其他记录。