连接两个表的最佳方式,其中1仅用于匹配


Best way to join two tables where 1 is for matching only

我已经做了一个多小时了,我很沮丧。我有两个表,我正在进行一个查询,其中一个表只用于检查单个条件,但目前我在第二个表中找到的条目都有重复的结果。

表格:客户&发票

第一个查询-获取所有人:

Select cust_id 
FROM Customers 
WHERE clinic_id='$clinic' 

这很好用,只是一个简单的查询。。。我的下一个目标是加入第二个表格,只显示过去18个月内发现的发票的结果。

查询:

Select Customers.cust_id 
FROM Customers 
LEFT JOIN Invoices 
ON Customers.cust_id=Invoices.cust_id 
WHERE Customers.clinic_id='$clinic' 
AND Invoices.invoice_date > '$cutoffdate'

这给了我过去18个月内发现的每张发票的结果,所以如果一个人有5张发票,该人会被退回5次。

我需要查询只返回每个人一次,并且只有当它在过去18个月内找到至少一张发票时。

如何修改我的查询以执行此操作?

我想展示两种方法来获得您描述的结果。

首先,如果您想只显示有发票的客户,您可能需要切换到INNER JOIN而不是LEFT JOIN。这将使所有没有任何发票的客户都无法获得您的结果,据我所知,这就是您想要存档的内容。更多关于JOIN s差异的信息可以在这里阅读。

1.DISTINCT

只需在SELECT之后添加DISTINCT,就可以指定从结果集中删除重复的行。

SELECT DISTINCT C.cust_id 
FROM Customers C
INNER JOIN Invoices I ON C.cust_id = I.cust_id 
WHERE C.clinic_id='$clinic' 
    AND I.invoice_date > '$cutoffdate'

2.GROUP BY

你可以使用GROUP BY来归档同样的效果,这通常是在你聚合其中的东西时使用的,例如,计算账单或将其相加。

SELECT C.cust_id 
FROM Customers C
INNER JOIN Invoices I ON C.cust_id = I.cust_id 
WHERE C.clinic_id='$clinic' 
    AND I.invoice_date > '$cutoffdate'
GROUP BY C.cust_id

最有效的方法是使用exists:

Select c.cust_id 
FROM Customers c 
WHERE EXISTS (SELECT 1
              FROM Invoices i
              WHERE c.cust_id = i.cust_id AND
                    c.clinic_id = '$clinic' AND
                    i.invoice_date > '$cutoffdate'
             );