mysql左外连接排除

时间:2017-06-19 16:25:53

标签: mysql join left-join

我有2张桌子' conta'和' details'并且两个表都具有空值和不同情况下的数据

conta
id  col1  col2  col3  col4
1  Hi  Bye  See YOU  
2  Hello  (NULL)  (NULL)  (NULL)

details

id  new_column1  new_column2  new_column3
1  bye  see  you

我想根据col2=new_column1 and col3 = new_column2 and col4 = new_column3应用加入并获取conta而不是details中的值,因此我的输出将是

conta
id  col1  col2  col3  col4
2  hello  (NULL)  (NULL)  (NULL)

但不知怎的,我无法这样做。我写下面的查询,但它根本没有得到我想要的值。

SELECT `id`,`col1`,`col2`,`col3`,`col4` FROM `conta`
WHERE LOWER(`col2`) + LOWER(`col3`) + LOWER(`col4`) NOT IN (SELECT DISTINCT(LOWER(`new_column1`) + LOWER(`new_column2`) + LOWER(`new_column3`))
 FROM `details`);

它只是给我没有结果!在显示屏中

任何帮助?

修改:我按照@Uueerdo的建议尝试了以下查询,但它并没有给我我想要的内容。

SELECT conta.id,`col1`,`col2`,`col3`,`col4` FROM `conta`
LEFT OUTER JOIN `details`
ON ((conta.col2 IS NULL AND details.new_column1 IS NULL) 
    OR (LOWER(conta.col2) = LOWER(details.new_column1)))
AND ((conta.col3 IS NULL AND details.new_column2 IS NULL) 
    OR (LOWER(conta.col3) = LOWER(details.new_column2)))
AND ((conta.col4 IS NULL AND details.new_column3 IS NULL) 
    OR (LOWER(conta.col4) = LOWER(details.new_column3)))
WHERE details.id IS NULL

col2的输出中,我看到一个值' 操作'它也出现在new_column1表的details中。这意味着它不应该出现在输出中,因为我正在尝试应用左外连接排除我甚至尝试使用LEFT JOIN而不是LEFT OUTER JOIN并且它也不工作

Edit2 :我找到了解决方案。查询工作并完成工作。执行我必须运行命令来替换我将连接应用于NULL值的列中的所有空白单元格。

4 个答案:

答案 0 :(得分:1)

您最好使用SELECT .... FROM a LEFT JOIN b ON conditions WHERE b.id IS NULL样式的查询;空比较有点不同(并且可以处理连接条件)。

例如,这些评估为NULL,这不是真的,这是假的:

  • NULL = NULL
  • NULL IN(NULL)

但你可以做这样的事情来更容易地比较空值:

  • ISNULL(a,x)= ISNULL(b,x)
  • (IS NULL和b IS NULL)

所以你加入条件可能是这样的:

[...]
ON ((conta.col2 IS NULL AND details.new_column1 IS NULL) 
    OR (LOWER(conta.col2) = LOWER(details.new_column1)))
AND ((conta.col3 IS NULL AND details.new_column2 IS NULL) 
    OR (LOWER(conta.col3) = LOWER(details.new_column2)))
[and so on...]
WHERE details.id IS NULL

这假定details具有某种非空行标识字段,可用于可靠地确定是否存在匹配。

编辑:您当前查询的确切问题(除了我之前概述的空问题)是+在MySQL中不是连接,它是补充。对于没有NULL值的行,您已为LOWER(col2) + LOWER(col3) + LOWER(col4)LOWER(new_column1) + LOWER(new_column2) + LOWER(new_column3)显示了产量0的数据。您需要使用CONCAT()函数来执行操作;但我不鼓励它,因为CONCAT('abc', 'def', '')等于CONCAT('ab', 'cd', 'ef')

旁注:DISTINCT不是一个函数,()将不起作用(除了它们会导致问题,如果它们包含多个结果字段

您可以通过以下格式进行简单更改来保留常规格式和上述空值问题:WHERE (a, b, c) IN (SELECT a, b, c FROM ....

答案 1 :(得分:0)

您可以执行左连接,然后在第二个表中测试null,以查找第一个表中与第二个表中的任何行不匹配的行。

SELECT 
    a.`id`,
    a.`col1`,
    a.`col2`,
    a.`col3`,
    a.`col4` 
FROM `conta` a
LEFT JOIN `details` b
ON a.`col2` like b.`new_column1`
    AND a.`col3` like b.`new_column2`
    AND a.`col4` like b.`new_column3`
WHERE b.`id` IS NULL

答案 2 :(得分:-1)

您可以使用EXISTS运算符创建反半连接。请看一下这个链接:https://www.techonthenet.com/mysql/exists.php

示例查询:

SELECT
    id,
    col1,
    col2,
    col3,
    col4
FROM conta
WHERE NOT EXISTS (
    SELECT 1
    FROM details
    WHERE conta.col2 LIKE details.new_column1
        AND conta.col3 LIKE details.new_column2
        AND conta.col4 LIKE details.new_column3
)

答案 3 :(得分:-1)

您的问题解决方案内部加入(联系表)与(详细信息表) 和get(contact。*)Contact.col1!= details.new_column1

的所有列

这是一个查询

Select conta.* from conta inner join details on conta.col1!=details.new_column1

你可以和更多内连接中的列