简体   繁体   English

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

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

I've got three tables: Clients, Services, and Client Locations. 我有三个表:“客户”,“服务”和“客户位置”。 I'm running a query that needs to return the locations of clients that received a certain service. 我正在运行一个查询,该查询需要返回接收某种服务的客户端的位置。 So using the second table in the SELECT and the third table in the WHERE. 因此,请使用SELECT中的第二个表和WHERE中的第三个表。 I'm using two LEFT JOINs and getting my results repeated in an undesirable way. 我使用了两个LEFT JOIN,并以一种不希望的方式使结果重复。

Here are simplified versions of the three tables... 这是三个表的简化版本...

Clients (clients) 客户(客户)

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

Client Services (services) Used only in the WHERE statement 客户服务(服务)仅在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

Client Locations (locations) Used only in the SELECT statement 客户端位置(位置)仅在SELECT语句中使用

id_client | city
----------------------
1         | Boston, MA
3         | Providence, RI

Here's The Query 这是查询

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'

The Results 结果

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

So it's giving me Abby living in Boston three times instead of the desired one. 因此,这给了我艾比住在波士顿的三倍,而不是理想的一次。

Now, I know exactly why this is happening. 现在,我确切知道为什么会这样。 The LEFT JOIN used for the services table is being used for the results and Abby's three counseling sessions are causing the city to be repeated three times. 服务表中使用的LEFT JOIN用于结果,而Abby的三次咨询会导致该城市重复三遍。

Is there another way to do this JOIN so that the services table doesn't cause repetition like this? 还有另一种方法可以做到这一点,以便服务表不会引起这样的重复吗? I've tried INNER JOIN and get the same thing. 我尝试了INNER JOIN并得到了同样的东西。

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

Or a group by 或一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

Or a subquery 或子查询

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

Sample SQL Fiddle 示例SQL提琴

Use exists : 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'
             );

Although you can use group by or distinct , this method should perform better. 尽管您可以使用group bydistinct ,但此方法应该会更好。 There is no need to generate the duplicated results just to remove them in another step. 无需仅在另一步骤中将其删除即可生成重复的结果。

You can get the distinct client ids for that serviceType and then join to client and location to get more details on the client. 您可以获取该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

You are summarizing a detail result set. 您正在汇总详细结果集。 So do that using DISTINCT. 使用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'

Or use a GROUP BY query and provide some summary statistics: 或使用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

You simply can use a distinct clause to avoid getting double results. 您只需使用一个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