Einzelnen Beitrag anzeigen

HeZa

Registriert seit: 4. Nov 2004
Ort: Dortmund
182 Beiträge
 
Delphi 10 Seattle Professional
 
#13

AW: Interbase: Merkwürdiges Verhalten bei LEFT OUTER JOIN

  Alt 9. Apr 2020, 12:17
Hallo,

erst mal allen vielen Dank.

Ich hatte gehofft, dass es einen simplen Work Around gibt. Darum hatte ich den Hinweis zu Klammern auch gleich mal ausprobiert. Das ändert aber leider nicht das Ergebnis.

Das Beispiel was ich gezeigt habe war so reduziert, um die Problematik zu zeigen.

Warum ich so etwas verwenden wollte, hängt mit den Gegebenheiten des Datenbankdesigns zusammen. Ich erspare es mir jetzt Gründe aufzuzählen warum manchmal eine komplexe SQL-Abfrage einer Änderung des Datenbankdesigns vorgezogen wird.

Für die Interessierten folgt ein SQL-Script, das die Auslösende Problematik besser wieder gibt. Die Basis Tabelle hat ein Referenzfeld. Diese Referenz kann abhängig von einem Typ-Feld auf zwei verschieden Tabellen verweisen, deren Ids auch noch die gleichen Werte haben können.

Interessant dabei ist, dass das 2. SELECT von Interbase mit einer Fehlermeldung quitiert wird und nur das 3.SELECT zum von mir erwarteten Ergebnis führt.
Code:
create table test (id int, ref_typ int, ref int);
create table test_1 (ref1 int, data1 int);
create table test_2 (ref2 int, data2 int);
 
insert into test (id, ref_typ, ref) values (1, 1, 1);
insert into test (id, ref_typ, ref) values (2, 2, 1);
insert into test (id, ref_typ, ref) values (3, 1, null);
insert into test (id, ref_typ, ref) values (4, 2, null);
insert into test_1 (ref1, data1) values (1, 100);
insert into test_2 (ref2, data2) values (1, 200);
 
-- führt zum erwarteten Ergebniss in MySQL, Oracle, PostgreSQL, SQLite, MS-SQL
select
  id, ref_typ, ref, coalesce(data1, data2) as data
from
  test
  left outer join test_1 on ref1 = ref and ref_typ = 1
  left outer join test_2 on ref2 = ref and ref_typ = 2;
 
-- führt zum erwarteten Ergebniss in MySQL, Oracle, PostgreSQL, SQLite, MS-SQL
select
  id, ref_typ, ref,
  case
    when ref_typ = 1 then (select data1 from test_1 where ref1 = ref)
    when ref_typ = 2 then (select data2 from test_2 where ref2 = ref)
  end as data
from
  test;
 
-- führt zum erwarteten Ergebniss in MySQL, Oracle, PostgreSQL, SQLite, MS-SQL, Interbase
select
  t.id, t.ref_typ, t.ref,
  case
    when t.ref_typ = 1 then (select t1.data1 from test_1 t1 where t1.ref1 = t.ref)
    when t.ref_typ = 2 then (select t2.data2 from test_2 t2 where t2.ref2 = t.ref)
  end as data
from
  test t;
 
drop table test;
drop table test_1;
drop table test_2;
Ich verwende jetzt eine Variante des 3. SELECT. Finde ich nicht schön, funktioniert aber.

Ciao HeZa
  Mit Zitat antworten Zitat