繁体   English   中英

三张桌子,两个联接,结果只需要一张桌子

[英]Three Tables, Two Joins, Only One Table Needed For Results

我有三个表:“客户”,“服务”和“客户位置”。 我正在运行一个查询,该查询需要返回接收某种服务的客户端的位置。 因此,请使用SELECT中的第二个表和WHERE中的第三个表。 我使用了两个LEFT JOIN,并以一种不希望的方式使结果重复。

这是三个表的简化版本...

客户(客户)

id_client | clientName
----------------------
1         | Abby
2         | Betty
3         | Cathy

客户服务(服务)仅在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

客户端位置(位置)仅在SELECT语句中使用

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'

结果

clientName | city
-----------------------
Abby       | Boston, MA
Abby       | Boston, MA
Abby       | Boston, MA

因此,这给了我艾比住在波士顿的三倍,而不是理想的一次。

现在,我确切知道为什么会这样。 服务表中使用的LEFT JOIN用于结果,而Abby的三次咨询会导致该城市重复三遍。

还有另一种方法可以做到这一点,以便服务表不会引起这样的重复吗? 我尝试了INNER JOIN并得到了同样的东西。

要么使用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'

或一group by

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

示例SQL提琴

exists用途:

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'
             );

尽管您可以使用group bydistinct ,但此方法应该会更好。 无需仅在另一步骤中将其删除即可生成重复的结果。

您可以获取该serviceType的不同客户端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

您正在汇总详细结果集。 使用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'

或使用GROUP BY查询并提供一些摘要统计信息:

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'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM