Почему я могу выбрать что-то из левого соединения в столбце NULL? (С надуманным примером для локального воспроизведения, возможно, ошибка!) - PullRequest
2 голосов
/ 04 октября 2009

версия Я использую версию сервера: 5.1.36-community-log MySQL Community Server (GPL)

Я наконец-то придумал простой пример, чтобы легко воспроизвести его!

установка:

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');

затем запустите:

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);

Итак, это как-то связано с первичным ключом!

НОВЫЙ НАЙДЕН

запустить это не вызовет ошибку:

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;

Так что это также как-то связано с направлением соединения!

Ответы [ 4 ]

1 голос
/ 04 октября 2009

Я только что запустил создание, вставку и выбор в MySQL 5.0.58, 5.0.82 и 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;
0 голосов
/ 04 октября 2009

Очень интересно. Это действительно похоже на ошибку в MySQL. Результат запроса зависит от того, есть ли первичные ключи или нет. Они определенно не должны влиять на результат. Для справки, PostgreSQL вернет правильный результат с первичными ключами, поэтому я думаю, что вряд ли это будет ожидаемое поведение.

0 голосов
/ 04 октября 2009

Ваш установочный код неправильный

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

Плюс убедитесь, что вы бросаете свои столы после каждого теста. Возможно, у вас есть неверные данные.

0 голосов
/ 04 октября 2009

Является ли, что одна из строк 'fid' в 'fuinfo' установлена ​​в NULL? MySQL мог бы соединить это со значением NULL в левой таблице.

...