0

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

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

我有一张包含客户的表格和一张包含该客户拥有的状态的表格。

如果我想查找客户已发生状态的结果,我已设法使用联接获得所需的结果,但有时我希望能够找到不仅已达到状态而且还有其他一些状态的客户状态还没有。

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

例如,客户可能具有发票状态和已付款状态。

如果我想查看哪些客户已开具发票,那很好,如果我想查看哪些客户已开具发票并已付款,那很好,但如果我想查看哪些客户已开具发票但未付款,那我就开始使用不存在子查询

还有另一种更有效的方法吗?或者这是最好的方法,但我需要弄清楚mysql如何将索引与这些表一起使用以提高效率?

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

谢谢

马特

4

1 回答 1

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

老实说,我建议您重新排列代码以删除 RIGHT OUTER JOIN。混合左右连接往往会非常混乱。

于 2012-12-06T12:16:23.477 回答