Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql查询使用需要EXIST和NOT EXIST结果的联接状态表查找结果_Mysql - Fatal编程技术网

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

mysql查询使用需要EXIST和NOT EXIST结果的联接状态表查找结果,mysql,Mysql,我一直在四处寻找解决我问题的办法 我有一些有用的东西,但我不确定这是最有效的做事方式,在谷歌搜索时找不到任何人尝试这样做 我有一张有客户的桌子,还有一张有客户状态的桌子 如果我想在某个客户的状态发生的情况下找到结果,我已经使用连接成功地获得了所需的结果,但有时我希望能够找到不仅已达到某个状态,而且还有一些其他状态尚未达到的客户 目前,我正在使用一个NOT EXISTS子查询执行此操作,但它似乎有点慢,如果我必须在再次通过所有结果找到与第一个状态匹配的结果后进行检查,以查看它是否与另一个状态不匹配

我一直在四处寻找解决我问题的办法

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

我有一张有客户的桌子,还有一张有客户状态的桌子

如果我想在某个客户的状态发生的情况下找到结果,我已经使用连接成功地获得了所需的结果,但有时我希望能够找到不仅已达到某个状态,而且还有一些其他状态尚未达到的客户

目前,我正在使用一个NOT EXISTS子查询执行此操作,但它似乎有点慢,如果我必须在再次通过所有结果找到与第一个状态匹配的结果后进行检查,以查看它是否与另一个状态不匹配,则可以解释此慢度

例如,客户的状态可以是“已开票”,状态可以是“已付款”

如果我想看看哪些客户已经开过发票,那很好,如果我想看看哪些客户已经开过发票并支付过款,那很好,但是如果我想看看哪些客户已经开过发票但没有支付过款,那我就必须使用一个不存在的子查询

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

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

谢谢


Matt

如果这是在多个客户机上进行的,那么通常的解决方案是为每个客户机的状态选择一个子集,然后使用左外部连接来连接该子集

差不多

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了。我认为您可以相当容易地将联接使用到subselect上,但是除了检查声明的状态是否为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

老实说,我建议您重新安排代码以删除正确的外部联接。混合使用左连接和右连接往往会让人非常困惑。

如果您添加您正在使用的查询和数据库结构库以实现超快速响应,这会非常有帮助,正如我完全理解的那样,您显示的示例是状态1和状态2尚未到达的位置,因此如果我需要它来确定位置,例如,状态1和2尚未达到,但状态3已达到。我是否可以在同一查询中执行另一个左联接,但这次不包括b.ClientId为NULL的位置,以便在有匹配项的位置返回结果?是的,几乎可以。您可能希望检查第二次联接的结果是否不为NULL,或者在第二次联接上,您可以使用内部联接而不是外部联接。像这样做子选择相当快,查询只需执行一次,而不是在其他情况下每行执行一次。作为左连接,无论在连接的右侧是否找到匹配项,它都会返回一行,WHERE用于排除找到匹配项的位置。我将在以后开始工作时告诉您我是如何实现这一点的,再次感谢您的帮助如果我想在设置状态3天后将其设置为非空,我可以使用状态日期将其添加到where语句中吗?如果我多次设置了一个状态,我可以使用MAX只在最近的状态之后进行计时吗?对于你的第一点,恐怕我需要更多的信息来说明你将如何做。对于第二点,您可以使用与上述类似的编码来确定最新状态更新的详细信息,即,您的子选择您使用一个连接来对另一个子选择进行连接