0

我的问题是:我的想法有什么问题?

为什么左连接没有像我想象的那样工作?

在这里给出了一个有效的答案(没有解释)。

更多信息。

我有这个 sql fiddle 显示我在使用左外连接时面临的问题

结构

CREATE TABLE IF NOT EXISTS `mychanges` (
  `object_id` int(11) unsigned NOT NULL,
  `version_stamp` datetime DEFAULT NULL,
  `object_name` varchar(255) DEFAULT NULL,
  `project` int(11) unsigned DEFAULT NULL,
  PRIMARY KEY (`object_id` ,`version_stamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

    INSERT INTO mychanges VALUES (1266, "2014-09-24 09:55:40", "bbbb", 2 );
    INSERT INTO mychanges VALUES (1236, "2014-09-24 09:55:40", "aaa", 2 );
    INSERT INTO mychanges VALUES (1226, "2014-09-24 09:55:40", "zzz", 5 );
    INSERT INTO mychanges VALUES (1216, "2014-09-24 09:55:40", "xxxx", 8 );

    INSERT INTO mychanges VALUES (1256, "2014-09-24 09:51:40", "name1", 10 );
    INSERT INTO mychanges VALUES (1256, "2014-09-24 09:52:40", "name2", 10 );
    INSERT INTO mychanges VALUES (1256, "2014-09-24 09:53:40", "name3", 10 );
    INSERT INTO mychanges VALUES (1256, "2014-09-24 09:54:40", "name4", null );
    INSERT INTO mychanges VALUES (1256, "2014-09-24 09:56:40", "name5", null );

选择

SELECT  mychanges.object_id AS objectid1, mychanges.object_name AS objectname1, mychanges.version_stamp AS version_stamp1, change2.project as project2, change2.version_stamp as version_stamp2, change2.object_name as objectname2 FROM mychanges
LEFT JOIN (SELECT * from mychanges AS x WHERE x.project IS NULL) AS change2
ON change2.object_id = mychanges.object_id 
WHERE  mychanges.project = 10

我想得到什么:

插入的值

INSERT INTO mychanges VALUES (1256, "2014-09-24 09:51:40", "name1", 10 );
INSERT INTO mychanges VALUES (1256, "2014-09-24 09:52:40", "name2", 10 );
INSERT INTO mychanges VALUES (1256, "2014-09-24 09:53:40", "name3", 10 );
INSERT INTO mychanges VALUES (1256, "2014-09-24 09:54:40", "name4", null );
INSERT INTO mychanges VALUES (1256, "2014-09-24 09:56:40", "name5", null );

所以用书面语言:作为项目的所有记录都是 10,并且所有记录具有相同的对象 ID 和项目 ID 为 10 的记录。

为什么?

这是一个变更集表。用户正在更改对象名称并按 Enter。这会以更改的形式生成条目。遗憾的是,这些更改的项目 id 可能为 null。对象 id 是唯一的。

我在想什么?

我想:是的,我们有所有 project_id 为 NULL 的条目。剩下的我们有 project_id 和 10 的所有记录。如果我们使用 加入它们object_id,我们会得到两个,没有重复。但相反,我们得到了 name4 和 name5 的重复项,而不是 name1、name2 和 name3。

为什么不?

4

1 回答 1

1

我想:是的,我们有所有 project_id 为 NULL 的条目。左边我们有 project_id 为 10 的所有记录。如果我们加入它们,我们会得到两个,没有重复

没有。您不能加入它,因为这些值NULL无法与任何其他值进行比较,甚至与NULL. 如果您有 null,则需要使用ifNULL()函数显式处理它。

编辑

再看一遍,我意识到您正在尝试加入object_id当然不是空的。因此,让我们看看您的查询中发生了什么。如果我可以将您的查询分为两部分,第一部分是:

SELECT  
mychanges.object_id AS objectid1, 
mychanges.object_name AS objectname1, 
mychanges.version_stamp AS version_stamp1
FROM mychanges
WHERE  mychanges.project = 10

这将产生 3 条记录object_id= 1256

第二部分是,

SELECT * from mychanges AS x WHERE x.project IS NULL

这会产生 2 条记录object_id= 1256。

当您使用条件连接这两个部分时change2.object_id = mychanges.object_id,它会在结果中产生 3 X 2 = 6 条记录。左侧的每条记录都是重复的,右侧有2条记录。

这正是 SQL 应该表现的。

于 2014-11-26T09:48:56.717 回答