简体   繁体   English

LEFT JOIN 右表中的缺失值

[英]LEFT JOIN missing values from the right table

I am trying to split a table into two referenced tables and am having issues with the population of one of the new tables.我正在尝试将一个表拆分为两个引用的表,并且在其中一个新表的填充方面存在问题。 Say the old table has columns A, B, C, X, Y, Z and the first new table to have A, B, C, ID and the second to be ID, X, Y, Z .假设旧表有A, B, C, X, Y, Z ,第一个新表有A, B, C, ID ,第二个有ID, X, Y, Z

Populating the second table is trivial:填充第二个表很简单:

INSERT INTO newTable2 (`X`,`Y`,`Z`)
SELECT DISTINCT `X`,`Y`,`Z`
FROM oldTable;

I can check newTable2 after this has been run and see that is populated properly.我可以在运行后检查newTable2并查看它是否正确填充。 ID is populated by the table definition and there are no null values. ID由表定义填充,并且没有空值。 I seem to have issues with populating the first table.我似乎在填充第一个表时遇到问题。 I attempted to use this script:我试图使用这个脚本:

INSERT INTO newTable1
SELECT oldTable.`A`
     , oldTable.`B`
     , oldTable.`C`
     , newTable2.`ID`
FROM oldTable
LEFT JOIN newTable2
ON newTable2.`X` = oldTable.`X`
    AND newTable2.`Y` = oldTable.`Y`
    AND newTable2.`Z` = oldTable.`Z`;

But when I check the resulting table I get null values for ID for most rows.但是当我检查结果表时,大多数行的ID为空值。 Due to how it's populated newTable2 should have a row and ID for every row of oldTable and every row with a null that I have checked manually has had a value that was simply not found.由于它的填充方式, newTable2应该为oldTable每一行都有一个行和ID ,而我手动检查过的每一行都有一个空值,但根本找不到。

I am running MySql 5.7 and all columns except ID are of the type varchar .我正在运行 MySql 5.7 并且除ID之外的所有列都是varchar类型。

Your JOIN condition does not handle NULL values.您的 JOIN 条件不处理 NULL 值。 You have to handle them if you want to get all your original values back.如果您想恢复所有原始值,则必须处理它们。

Use something like this for each columns which can contain NULL values.对可以包含 NULL 值的每一列使用类似的东西。

(newTable2.`X` = oldTable.`X` OR (newTable2.`X` IS NULL AND oldTable.`X` IS NULL))

As @Pred mentioned you should handle the NULL case in your Join statements.正如@Pred 提到的,您应该在 Join 语句中处理 NULL 情况。 I would use the null-safe <=> operator to avoid the OR statement:我会使用空安全<=>运算符来避免 OR 语句:

Something like the following:类似于以下内容:

 INSERT INTO newTable1
    SELECT oldTable.`A`
         , oldTable.`B`
         , oldTable.`C`
         , newTable2.`ID`
    FROM oldTable
    LEFT JOIN newTable2
    ON newTable2.`X` <=> oldTable.`X`
        AND newTable2.`Y` <=> oldTable.`Y`
        AND newTable2.`Z` <=> oldTable.`Z`;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM