查询表A中与表B中的行不匹配的行

时间:2013-11-18 23:34:49

标签: php mysql sql

我有两张桌子:

http://imageshack.us/f/854/7jpd.png/

我需要第一张表中的“clientes.id_cliente,clientes.nombre,clientes.apellido,clientes.empresa,clientes.correo”,但删除第二张表中出现的人(合同的人)

我试过这个(以及其他许多事情):

SELECT clientes.id_cliente, clientes.nombre, clientes.apellido, clientes.empresa, clientes.correo
FROM clientes
INNER JOIN contratos_clientes
ON clientes.id_cliente != contratos_clientes.id_cliente

这就是结果:

enter image description here

我尝试了不同的方法,但我什么都没有。

2 个答案:

答案 0 :(得分:1)

您需要NOT EXISTS查询:

SELECT clientes.id_cliente, 
       clientes.nombre, 
       clientes.apellido, 
       clientes.empresa, 
       clientes.correo
FROM clientes
WHERE NOT EXISTS (select 1 
                  from contratos_clientes
                  where clientes.id_cliente = contratos_clientes.id_cliente);

另一种选择是NOT IN

SELECT clientes.id_cliente, 
       clientes.nombre, 
       clientes.apellido, 
       clientes.empresa, 
       clientes.correo
FROM clientes
WHERE clientes.id_cliente NOT IN (select contratos_clientes.id_cliente 
                                  from contratos_clientes
                                  where contratos_clientes.id_cliente IS NOT NULL);

子查询中的IS NOT NULL是必需的,因为如果为NOT IN列返回NULL值,contratos_clientes.id_cliente运算符将失败。如果该列定义为NOT NULL,则可以删除该条件。

众所周知,MySQL在NOT IN语句中非常糟糕,因此第一个可能会表现得更好。

答案 1 :(得分:1)

从概念上讲,这是NOT EXISTSNOT IN - 但可能无法很好地优化。如果@a_horse_with_no_name发布的查询效果不佳,您也可以执行以下操作:

SELECT clientes.id_cliente, clientes.nombre, clientes.apellido,
        clientes.empresa, clientes.correo
FROM clientes
LEFT JOIN contratos_clientes
ON clientes.id_cliente = contratos_clientes.id_cliente
WHERE contratos_clientes.id_cliente IS NULL

LEFT JOIN要求左表(此处为clientes表)中的所有行,并在右表(ON中加入相应的行(由contratos_clientes定义) })如果它们存在。对于左侧的每一行,如果给定行的值不存在,则右表中该行部分的所有值都将为NULL。在您的情况下,这些是您想要的行 - 所以只需检查右侧的值是否为NULL。最好使用一个不能NULL的值,例如PK字段。

顺便提一下,这种查询 - “A中与B中的行不匹配的行” - 称为反连接。

(注意:通常当你只想要JOIN的左边部分时,你需要使用SELECT DISTINCT,这样如果左侧的给定行与右边的多行匹配,它将删除重复项。但是在这种情况下,您只需要在右侧查找NULL行,并且左侧每行最多插入一个这样的“虚拟”行,因此您不能重复,因此不需要DISTINCT。)

相关问题