Mysql 三个表,两个连接,结果只需要一个表
我有三个表:客户、服务和客户位置。我正在运行一个查询,需要返回接收特定服务的客户端的位置。因此,使用SELECT中的第二个表和WHERE中的第三个表。我正在使用两个左连接,并以不希望的方式重复我的结果 下面是三个表的简化版本 客户(客户) 客户端服务(服务)仅在WHERE语句中使用Mysql 三个表,两个连接,结果只需要一个表,mysql,sql,join,Mysql,Sql,Join,我有三个表:客户、服务和客户位置。我正在运行一个查询,需要返回接收特定服务的客户端的位置。因此,使用SELECT中的第二个表和WHERE中的第三个表。我正在使用两个左连接,并以不希望的方式重复我的结果 下面是三个表的简化版本 客户(客户) 客户端服务(服务)仅在WHERE语句中使用 id_client | date | serviceType ----------------------------------- 1 | 1/5/2015 | Counseling 1
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列(我知道我在帖子中没有显示),这样我就可以得到我想要的结果。但愿我能做出两个正确的答案!