Hallo mark,
ich habe das gerade minimalistisch nachzustellen versucht - bei mir tritt dieser Effekt nicht auf.
CREATE TEMPORARY TABLE IF NOT EXISTS lang (
      locale VARCHAR(6) DEFAULT NULL
);
INSERT INTO lang (locale) VALUES ('de_DE'),('en_US'),('it_IT'),('fr_FR');
CREATE TEMPORARY TABLE IF NOT EXISTS texte (
      locale VARCHAR(6) DEFAULT NULL,
      id     VARCHAR(6) DEFAULT NULL,
      textid VARCHAR(6) DEFAULT NULL
);
INSERT INTO texte (locale, id, textid) VALUES 
   ('de_DE', '0001', '0001'),   ('en_US', '0002', '0001'),   ('it_IT', '0003', '0001'),
   ('de_DE', '0011', '0002'),   ('en_US', '0012', '0002'),   ('it_IT', '0013', '0002');
select * 
from lang left join texte on lang.locale = texte.locale
where textid='0002' or textid is null
Die fr_FR Zeile ist im Ergebnis drin, und das ist so auch zu erwarten.
D.h. bei Dir kommt noch irgend ein anderer Effekt hinzu, den du uns nicht zeigst.
Rolf
-- 
sumpsi - posui - clusi
  sumpsi - posui - clusi
 nicht angemeldet
 nicht angemeldet Rolf B
 Rolf B