2009-10-04 7 views
2

VERSION J'utilise la version du serveur: 5.1.36-community-log MySQL Community Server (GPL)Pourquoi est-ce que je peux choisir quelque chose hors de la jointure gauche sur une colonne NULL? (Avec l'exemple inventé pour le reproduire localement, probablement un bogue!)

J'ai finalement trouvé un exemple facile à reproduire facilement!

configuration:

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

puis exécutez:

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; 

obtiendra ce tort: ​​

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

Mais si nous créons t2 de cette façon, il ne se produira pas:

create table t2(id integer unsigned); 

Donc, ça a quelque chose à voir avec la clé primaire!

NOUVEAU TROUVE

terme, cela ne déclenchera pas le 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; 

Il a aussi quelque chose à voir avec la direction rejoindre!

+1

À quoi ressemble le reste de vos tableaux? – random

+1

Est-il possible que la jointure soit optimisée? Exécutez une explication sur la requête pour voir ce qui se passe ... – Zed

+1

s'il vous plaît au lieu d'afficher les résultats de vos requêtes juste nous montrer toutes vos tables avec leurs contenus respectifs! – markus

Répondre

0

Est-ce que l'une des lignes 'fid' dans 'fuinfo' est définie sur NULL? MySQL pourrait se joindre à cela avec une valeur NULL dans la table de gauche.

+0

Mais ce n'est pas réglé sur NULL, c'est ici réglé sur "Tiger"! – Misier

+1

fuinfo.name est défini sur "Tiger", mais il peut être jumelé avec une ligne dans les réponses où lefId est NULL. – Jez

+0

Mais j'ai spécifié la condition de jointure comme étant: ON f.id = a.lefId – Misier

0

Très intéressant. Cela ressemble en effet à un bug dans MySQL. Le résultat de la requête dépend s'il existe des clés primaires ou non. Ils ne devraient absolument pas affecter le résultat. Pour la référence, PostgreSQL retournera le résultat correct avec les clés primaires, donc je pense qu'il est peu probable que ce soit un comportement attendu.

+0

Puis-je être payé pour signaler ou découvrir un bug? – Misier

0

Votre code de configuration est erroné

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 être sûr que vous déposez vos tables après chaque test. Vous avez probablement de mauvaises données en eux.

+0

C'est une faute de frappe, s'il vous plaît essayez-le localement, vous rencontrerez certainement le même problème! – Misier

+0

Il fonctionne bien dans MSSQL, peut-être vous devriez spécifier votre SGBD dans le titre ou dans le corps, au lieu de seulement les balises. –

+0

Je n'aime pas être en double! – Misier

1

Je viens couru de créer, insérer et sélectionnez sur MySQL 5.0.58, 5.0.82 & 5.1.35 et j'ai reçu le résultat suivant, que je pense est correct:

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

Voici exactement ce que J'ai utilisé:

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

Oh, alors ce doit être un bug introduit avec la version du serveur: 5.1.36-community-log MySQL Community Server (GPL) – Misier

+0

Je doute qu'entre 5.1.35 et 5.1.36 ils auraient introduit ce gros bug. Avez-vous confirmé que votre SQL correspond à ce que vous avez posté (et ce que j'ai posté)? –

+0

Génial! J'ai également constaté qu'il est causé par la direction de jointure! S'il vous plaît exécuter ceci: sélectionnez t2. *, T3. * de t1 gauche rejoindre t2 sur t1.link = t2.id gauche rejoindre t3 sur t3.id = t2.id où t1.id = 1; – Misier

Questions connexes