Mysql 三个表,两个连接,结果只需要一个表

Mysql 三个表,两个连接,结果只需要一个表,mysql,sql,join,Mysql,Sql,Join,我有三个表:客户、服务和客户位置。我正在运行一个查询,需要返回接收特定服务的客户端的位置。因此,使用SELECT中的第二个表和WHERE中的第三个表。我正在使用两个左连接,并以不希望的方式重复我的结果 下面是三个表的简化版本 客户(客户) 客户端服务(服务)仅在WHERE语句中使用 id_client | date | serviceType ----------------------------------- 1 | 1/5/2015 | Counseling 1

我有三个表:客户、服务和客户位置。我正在运行一个查询,需要返回接收特定服务的客户端的位置。因此,使用SELECT中的第二个表和WHERE中的第三个表。我正在使用两个左连接,并以不希望的方式重复我的结果

下面是三个表的简化版本

客户(客户)

客户端服务(服务)仅在WHERE语句中使用

id_client | date      | serviceType
-----------------------------------
1         | 1/5/2015  | Counseling
1         | 1/12/2015 | Counseling
1         | 1/19/2015 | Counseling
2         | 1/21/2015 | Sup. Group
id_client | city
----------------------
1         | Boston, MA
3         | Providence, RI
客户端位置(位置)仅在SELECT语句中使用

id_client | date      | serviceType
-----------------------------------
1         | 1/5/2015  | Counseling
1         | 1/12/2015 | Counseling
1         | 1/19/2015 | Counseling
2         | 1/21/2015 | Sup. Group
id_client | city
----------------------
1         | Boston, MA
3         | Providence, RI
这里是查询

SELECT clients.clientName,locations.city
FROM clients
LEFT JOIN locations ON clients.id_client=locations.id_client
LEFT JOIN services ON clients.id_client=services.id_client
WHERE services.serviceType='Counseling'
结果

id_client | clientName
----------------------
1         | Abby
2         | Betty
3         | Cathy
clientName | city
-----------------------
Abby       | Boston, MA
Abby       | Boston, MA
Abby       | Boston, MA
所以这让艾比在波士顿住了三次,而不是理想中的一次

现在,我确切地知道为什么会发生这种情况。用于服务表的左连接用于结果,Abby的三次咨询会议导致城市重复三次


是否有其他方法进行此连接,以便服务表不会导致这样的重复?我尝试了内部联接,得到了同样的结果。

您正在总结一个详细的结果集。因此,请使用DISTINCT

SELECT DISTINCT clients.clientName, locations.city
  FROM clients
  LEFT JOIN locations ON clients.id_client=locations.id_client
  LEFT JOIN services ON clients.id_client=services.id_client
 WHERE services.serviceType='Counseling'
或者使用分组查询并提供一些汇总统计信息:

SELECT DISTINCT clients.clientName, locations.city,
       COUNT(*) service_count
  FROM clients
  LEFT JOIN locations ON clients.id_client=locations.id_client
  LEFT JOIN services ON clients.id_client=services.id_client
 WHERE services.serviceType='Counseling' 
 GROUP BY clients.clientName, locations.city

使用
distinct

SELECT DISTINCT clients.clientName,locations.city
FROM clients
LEFT JOIN locations ON clients.id_client=locations.id_client
LEFT JOIN services ON clients.id_client=services.id_client
WHERE services.serviceType='Counseling'
分组方式

SELECT clients.clientName,locations.city
FROM clients
LEFT JOIN locations ON clients.id_client=locations.id_client
LEFT JOIN services ON clients.id_client=services.id_client
WHERE services.serviceType='Counseling'
GROUP BY clients.clientName,locations.city
或子查询

SELECT clients.clientName,locations.city
FROM clients
LEFT JOIN locations ON clients.id_client=locations.id_client
LEFT JOIN (
  SELECT id_client, serviceType 
  FROM services 
  GROUP BY id_client, serviceType 
) services ON clients.id_client=services.id_client
WHERE services.serviceType='Counseling'
GROUP BY clients.clientName,locations.city

您可以获取该服务类型的不同客户端ID,然后加入到客户端和位置以获取有关客户端的更多详细信息

SELECT clients.clientName,locations.city
FROM 
(Select distinct id_client from services WHERE services.serviceType='Counseling') s
INNER JOIN clients ON clients.id_client = s.id_client
LEFT JOIN locations ON clients.id_client=locations.id_client

使用
存在

SELECT c.clientName, l.city
FROM clients c JOIN
     locations l
     ON c.id_client = l.id_client
WHERE EXISTS (SELECT 1
              FROM services s
              WHERE c.id_client = s.id_client AND
                    s.serviceType = 'Counseling'
             );

尽管您可以使用
分组方式
区分方式
,但此方法的性能应该更好。不需要生成重复的结果,只需在另一个步骤中删除它们。

您只需使用distinct子句即可避免获得双重结果

SELECT distinct clients.clientName,locations.city
FROM clients
LEFT JOIN locations ON clients.id_client=locations.id_client
LEFT JOIN services ON clients.id_client=services.id_client
WHERE services.serviceType='Counseling'

您应该注意,您的查询在服务上使用了一个左连接,其中where子句中的条件基本上使其成为一个内部连接。我觉得这个答案是最好的,因为它以最有效的方式解决了我发布的问题。不幸的是,我的实际情况比我发布的要复杂得多,这将是一场噩梦,要实现它,相关子查询的性能更好吗?比我的答案还要好?我很难真正了解这里的性能差异。我对你提出的另一种方法投了赞成票。最后,它们都是我所发布内容的有效解决方案,但我最终不得不做一些稍微不同的事情来解决我的实际问题。@dotjoe。我希望相关子查询比显式
select distinct
子查询的子查询性能更好。我希望在
服务(id\u客户端,service\u类型)
上使用适当的索引会快得多。有趣的是,我一直认为它会慢得多,因为它必须为每个id\u客户端运行exists。也许它会优化它?一开始我觉得这不管用,因为在某些情况下,一个人会有两次相同的位置,这需要反映在结果中,而不是归结为一次。但后来我意识到,我可以使用groupby和GROUP-id\u-client和id\u-location列(我知道我在帖子中没有显示),这样我就可以得到我想要的结果。但愿我能做出两个正确的答案!