mysql查询使用需要EXIST和NOT EXIST结果的联接状态表查找结果

时间:2012-12-06 11:58:41

标签: mysql

我一直在寻找解决问题的方法。

我有一些有用的东西,但我不确定这是最有效的做事方式,在谷歌搜索时找不到任何人试图这样做。

我有一张客户表和一张表,其中包含客户所拥有的状态。

如果我想找到客户已经发生状态的结果,我已经设法通过加入获得了所需的结果,但有时我希望能够找到不仅已达到状态而且已到达的客户还有一些其他状态。

目前我正在使用NOT EXISTS Sub查询执行此操作但看起来有点慢并且考虑一下如果我必须在找到与第一个状态匹配的结果之后通过所有结果再次检查它以查看它是否不匹配另一个它可以解释缓慢。

例如,客户可以具有开票状态和付款状态。

如果我想知道哪些客户已开具发票那么好,如果我想查看哪些客户已开具发票并付款那么好,但如果我想查看哪些客户已开具发票但未付款那就是我开始有使用NOT EXIST子查询

还有另一种更有效的解决方法吗?或者这是最好的方法,但我需要弄清楚mysql如何使用这些表格中的indx来提高效率?

如果有帮助,我可以提供实际sql的更多细节吗?

由于

马特

1 个答案:

答案 0 :(得分:0)

如果这是多个客户端,那么通常的解决方案是对每个客户端的状态进行子选择,然后使用LEFT OUTER JOIN来连接它。

这样的东西
SELECT *
FROM Clients a
LEFT OUTER JOIN (SELECT ClientId, COUNT(*) FROM ClientsStatus WHERE Status IN (1,2) GROUP BY ClientId) b
ON a.ClientId = b.ClientId
WHERE b.ClientId IS NULL

这个(非常粗略)的例子是给你一个状态为1或2的客户列表。

您应该能够扩展这个基本想法,以涵盖您正在处理的场景/数据

编辑以下

我玩过你的SQL。我认为你可以很容易地在子选择中使用JOIN,但除了索赔的状态是3还是95之外,这似乎没有检查任何其他内容。

SELECT claims.ID, claims.vat_rate, claims.com_rate,
claims.offer_val, claims.claim_value, claims.claim_ppi_amount, claims.claim_amount, claims.approx_loan_val, claims.salutationsa, claims.first_namesa, claims.last_namesa, 
clients.salutation, clients.first_name,clients.last_name, clients.phone, clients.phone2, clients.mobile, clients.dob,clients.postcode, clients.address1, clients.address2, clients.town, client_claim_status.person,clients.ID 
AS client_id,claims.ID AS claim_id, claims.date_added AS status_date_added,client_claim_status.date_added AS last_client_claim_status_date_added,work_suppliers.name AS refname, financial_institution.name AS lendname, clients.date_added AS client_date_added,ppi_claim_type_2.claim_type AS ppi_claim_type_name 
FROM claims 
RIGHT JOIN clients ON claims.client_id = clients.ID 
RIGHT JOIN client_claim_status 
ON claims.ID = client_claim_status.claim_id 
AND client_claim_status.deleted != 'yes' 
AND ((client_claim_status.status_id IN (1, 170)) 
AND client_claim_status.date_added < '2012-12-02 00:00:00' ) 
LEFT OUTER JOIN (SELECT claim_id FROM client_claim_status WHERE status_id IN (3, 95 )) Sub1
ON claims.ID = Sub1.claim_id
LEFT JOIN financial_institution ON claims.claim_against = financial_institution.ID 
LEFT JOIN work_suppliers ON clients.work_supplier_id = work_suppliers.ID 
LEFT JOIN ppi_claim_type_2 ON claims.ppi_claim_type_id = ppi_claim_type_2.ID 
WHERE claims.deleted != 'yes' 
AND Sub1.claim_id IS NULL
ORDER BY last_client_claim_status_date_added DESC

我建议您重新排列代码以删除正确的外部联接,但说实话。混合左右连接往往非常混乱。