为什么我可以从 NULL 列的左连接中选择一些内容?(用人为的示例在本地重现它,可能是一个错误!)

发布于 2024-08-06 09:18:41 字数 1066 浏览 6 评论 0原文

版本 我正在使用服务器版本:5.1.36-community-log MySQL Community Server (GPL)

我终于设计了一个简单的示例来轻松重现它!

setup:

create table t1(id integer unsigned,link integer unsigned);
create table t2(id integer unsigned auto_increment,primary key(id));
create table t3(id integer unsigned,content varchar(30));
insert into t1 value(1,null);
insert into t2 value(1);
insert into t3 value(1,'test');

then run:

select t2.*,t3.* 
from t1
left join t2 on t1.link=t2.id
left join t3 on t3.id=t2.id
where t1.id=1;

会得到这个错误:

+------+------+---------+
| id   | id   | content |
+------+------+---------+
| NULL |    1 | test    |
+------+------+---------+

但是如果我们以这种方式创建 t2,它就不会发生:

create table t2(id integer unsigned);

所以,它与主键有关!

NEW FOUND

运行这个不会触发错误:

select t2.*,t3.*
from t1
left join t2 on t1.link=t2.id
left join t3 on t2.id=t3.id
where t1.id=1;

所以它也与连接方向有关!

VERSION
I'm using Server version: 5.1.36-community-log MySQL Community Server (GPL)

I've finally contrived a easy example to reproduce it easily!

setup:

create table t1(id integer unsigned,link integer unsigned);
create table t2(id integer unsigned auto_increment,primary key(id));
create table t3(id integer unsigned,content varchar(30));
insert into t1 value(1,null);
insert into t2 value(1);
insert into t3 value(1,'test');

then run:

select t2.*,t3.* 
from t1
left join t2 on t1.link=t2.id
left join t3 on t3.id=t2.id
where t1.id=1;

will get this wrongly:

+------+------+---------+
| id   | id   | content |
+------+------+---------+
| NULL |    1 | test    |
+------+------+---------+

But if we create t2 this way,it won't happen:

create table t2(id integer unsigned);

So,it has something to do with primary key!

NEW FOUND

run this will not trigger the bug:

select t2.*,t3.*
from t1
left join t2 on t1.link=t2.id
left join t3 on t2.id=t3.id
where t1.id=1;

So it also has something to do with join direction!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

稚气少女 2024-08-13 09:18:41

我刚刚在 MySQL 5.0.58、5.0.82 和 5.0.82 上运行了 you create、insert 和 select。 5.1.35,我收到了以下结果,我认为这是正确的:

+------+------+---------+
| id   | id   | content |
+------+------+---------+
| NULL | NULL | NULL    |
+------+------+---------+

这正是我使用的:

CREATE TABLE `t1` (
  `id` int(10) unsigned default NULL,
  `link` int(10) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `t1` VALUES (1, NULL); 

CREATE TABLE `t2` (
  `id` int(10) unsigned NOT NULL auto_increment,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

INSERT INTO `t2` VALUES (1);

CREATE TABLE `t3` (
  `id` int(10) unsigned default NULL,
  `content` varchar(30) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `t3` VALUES (1, 'test');

SELECT t2.id, t3.id, t3.content
FROM t1
LEFT JOIN t2 ON t1.link = t2.id
LEFT JOIN t3 ON t2.id = t3.id
WHERE t1.id = 1;

I just ran you create, insert and select on MySQL 5.0.58, 5.0.82 & 5.1.35 and I received the following result, which I think is correct:

+------+------+---------+
| id   | id   | content |
+------+------+---------+
| NULL | NULL | NULL    |
+------+------+---------+

Here is exactly what I used:

CREATE TABLE `t1` (
  `id` int(10) unsigned default NULL,
  `link` int(10) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `t1` VALUES (1, NULL); 

CREATE TABLE `t2` (
  `id` int(10) unsigned NOT NULL auto_increment,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

INSERT INTO `t2` VALUES (1);

CREATE TABLE `t3` (
  `id` int(10) unsigned default NULL,
  `content` varchar(30) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `t3` VALUES (1, 'test');

SELECT t2.id, t3.id, t3.content
FROM t1
LEFT JOIN t2 ON t1.link = t2.id
LEFT JOIN t3 ON t2.id = t3.id
WHERE t1.id = 1;
江城子 2024-08-13 09:18:41

是否“fuinfo”中的“fid”行之一设置为 NULL? MySQL 可能会将其与左表中的 NULL 值连接起来。

Is it that one of the 'fid' rows in 'fuinfo' is set to NULL? MySQL could be joining that up with a NULL value in the left table.

棒棒糖 2024-08-13 09:18:41

非常有趣。这看起来确实像是 MySQL 中的一个错误。查询的结果取决于是否有主键。它们绝对不应该影响结果。作为参考,PostgreSQL 将返回带有主键的正确结果,因此我认为这不太可能是预期的行为。

Very interesting. This indeed does look like a bug in MySQL. The result of the query depends on whether there are primary keys or not. They should definitely not affect the result. For the reference, PostgreSQL will return the correct result with primary keys, so I think it's unlikely that it would be an expected behavior.

暗恋未遂 2024-08-13 09:18:41

您的设置代码是错误的

create table t1(id integer unsigned,link integer unsigned);  
create table t2(id integer unsigned auto_increment,primary key(id));  
create table t2(id integer unsigned,content varchar(30));

             ^^  This is wrong. Should be t3

另外,请确保在每次测试后删除表格。您可能有一些错误的数据。

Your setup code is wrong

create table t1(id integer unsigned,link integer unsigned);  
create table t2(id integer unsigned auto_increment,primary key(id));  
create table t2(id integer unsigned,content varchar(30));

             ^^  This is wrong. Should be t3

Plus be sure you drop your tables after each test. You probably have some wrong data in them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文