Abfrage mehrerer Tabellen (Joins)

Anfang  Zurück  Vor

Letzte Änderung 13.02.2014

 

In relationalen Datenmodellen werden Datensätze i.d.R. nicht in einer einzigen Tabelle abgespeichert, sondern über mehrere Tabellen verteilt, die dann miteinander in Beziehung stehen (Relation). Bei aufwändigeren Datenbankabfragen müssen daher meist mehrere Datenbank-Tabellen abgefragt (Joins) und die Daten zu einem gemeinsamen Abfrageergebnis zusammengeführt werden. Entsprechende SQL-Anweisungen können in der Praxis sehr komplex werden. Mit dem Query-Assistenten lassen sich jedoch selbst komplexeste Abfragen ganz leicht und schnell zusammen klicken.

 

Für die Abfrage über mehrere Tabellen müssen Sie zunächst jedoch ein ER-Diagramm anlegen, welches die Relationen zwischen den verwendeten Tabellen dokumentiert. In der Datenbank bereits gespeicherten Relationen können importiert werden. Mit den Informationen aus dem ER-Diagramm kann der Query Assistent eine hierarchische Baumstruktur generieren, sodass Sie für eine Abfrage über mehrere Tabellen nur noch systematisch alle Datenfelder anklicken müssen, die Sie abfragen möchten. Die notwendigen Join-Bedingungen werden automatisch generiert.

 

 

ER-Diagramm für das folgende Tutorial

 

clip0016

 

 

Datenbankabfrage über mehrere Tabellen

 

1.Geben Sie im Code-Editor die Anweisung XDEV.Query ein und drücken Sie Eingabe, sodass sich der Query-Assistent öffnet.

2.Wählen Sie unter Datenquelle und Ziel bei Quelle (Datenbank) die Datenquelle fahrzeugeDB aus.

3.Klicken Sie bei Quelle (Datenbank) die Datenbank-Tabelle FAHRZEUGE an, um alle Datenfelder dieser Tabelle zu selektieren.

4.Öffnen Sie den Zweig bei MODELL_ID <> MODELLE und selektieren Sie das Datenfeld MODELL.

5.Öffnen Sie den Zweig bei HERSTELLER_ID <> HERSTELLER und selektieren Sie das Datenfeld MARKE.

clip0017

6.Lassen Sie sich eine Virtuelle Tabelle generieren, in die das Abfrageergebnis übertragen werden soll. Klicken Sie dazu bei Ziel (Virtuelle Tabelle) auf vt_guide und wählen Sie im folgenden Menü Virtuelle Tabelle erstellen aus. Benennen Sie die Virtuelle Tabelle im folgenden Dialog bei Name mit FAHRZEUGE_JOIN und bestätigen Sie mit OK.

7.Legen Sie fest, ob das Abfrageergebnis vor dem ersten Datensatz der Virtuellen Tabelle eingefügt, hinter dem letzten Datensatz angehängt oder ob ggf. existierende Daten einfach überschrieben werden sollen. Klicken Sie dazu bei Ziel (Virtuelle Tabelle) auf vt_overwrite und wählen Sie die Option Überschreibend, Vorne einfügen oder Hinten anhängen aus.

clip0018

8.Klicken Sie im Query-Assistenten auf OK, um den Assistenten zu schließen.

 

 

Hinweise:

Datenbankabfragen mit XDEV.Query müssen immer in einer Try-Catch Anweisung stehen. Über eine Tooltip Funktion können Sie sich die Try-Catch Anweisung automatisch generieren lassen.

Für jede Datenbankabfrage sollten Sie das Abfrageergebnis mit Hilfe einer Abfragebedingung (WHERE) oder eines Limits eingrenzen, da es bei großen Datenmengen ansonsten leicht zu einem Speicherüberlauf kommen kann. Entsprechende Ergänzungen können Sie im Query-Assistenten bei Filter sowie bei Anzahl Treffer vornehmen.

 

 

 

Korrekte Selektierung von Datensatz IDs bei Joins

 

Das hinzujoinen von Datensatz IDs ist im Query-Assistent nur durch die Selektierung des Fremdschlüssels in der äußeren Tabelle möglich. Die Selektierung des Primärschlüssels in der inneren Tabelle führt dagegen zu einer Exception.    

 

Korrekte Selektierung

clip0337

Führt den Join wie gewünscht aus.

 

Fehlerhafte Selektierung

clip0338

Führt zu einer Exception.

 

 

 

Hinweis auf nicht verknüpfte Datenfelder

 

Sobald Sie im Query-Assistenten Datenfelder einer Datenbank-Tabelle selektieren, beginnt der Assistent automatisch mit der Suche nach einer geeigneten, namensgleichen Virtuellen Ziel-Tabelle und versucht die Datenfelder an Hand übereinstimmender Datenfeldnamen richtig zu mappen. Stellt der Assistent dabei fehlende Datenfelder in der Virtuellen Ziel-Tabelle fest, werden die Datenfelder, die nicht zugewiesen werden können, automatisch mit dem Warn-Symbol warning16 gekennzeichnet, womit der Assistent darauf hinweist, dass die vorgeschlagene Virtuelle Tabelle nicht als Ziel-Tabelle verwendet werden kann. In so einem Fall können Sie vom Assistenten eine für die Abfrage maßgeschneiderte, neue Virtuelle Tabelle generieren lassen, indem Sie auf vt_guide klicken. Grundsätzlich können Sie sich die vorgeschlagene Virtuelle Tabelle vom Assistenten mit den fehlenden Datenfeldern auch erweitern lassen. Dies ist jedoch nicht empfehlenswert, falls Sie diese Virtuelle Tabelle bereits an einer anderer Stelle im Programm verwenden.

 

 

 

Joins selber definieren

 

Bei Joins können Sie festlegen, ob es sich um einen Inner, Left, Right oder Outer Join handeln soll. Standardmäßig definiert der Query-Assistent immer einen Inner-Join. Im rechten Bereich des Query-Assistenten bei Joins können Sie die automatisch generierten Join-Bedingungen darüber hinaus individuell anpassen.

 

clip0019

 

 

clip0020

 

 

Generierter Code

 

try

{

   XDEV.Query(new QueryFahrzeuge());

}

catch(DBException e)

{

   e.printStackTrace();

}

 

 

   private static class QueryFahrzeuge extends Query
   {
      QueryFahrzeuge()
      {
         setDataSource(fahrzeugeDB.DB);
         
         select("FAHRZEUGE","ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_ID);
         select("FAHRZEUGE","BILDPFAD").into(FAHRZEUGE_JOIN.FAHRZEUGE_BILDPFAD);
         select("MODELLE","MODELL").into(FAHRZEUGE_JOIN.MODELLE_MODELL);
         select("HERSTELLER","MARKE").into(FAHRZEUGE_JOIN.HERSTELLER_MARKE);
         select("FAHRZEUGE","LEISTUNG").into(FAHRZEUGE_JOIN.FAHRZEUGE_LEISTUNG);
         select("FAHRZEUGE","ERSTZULASSUNG").into(FAHRZEUGE_JOIN.FAHRZEUGE_ERSTZULASSUNG);
         select("FAHRZEUGE","KILOMETERSTAND").into(FAHRZEUGE_JOIN.FAHRZEUGE_KILOMETERSTAND);
         select("FAHRZEUGE","FAHRZEUGTYP_ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_FAHRZEUGTYP_ID);
         select("FAHRZEUGE","FAHRZEUGART_ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_FAHRZEUGART_ID);
         select("FAHRZEUGE","KRAFTSTOFF_ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_KRAFTSTOFF_ID);
         select("FAHRZEUGE","GETRIEBE_ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_GETRIEBE_ID);
         select("FAHRZEUGE","FARBE_ID").into(FAHRZEUGE_JOIN.FAHRZEUGE_FARBE_ID);
         select("FAHRZEUGE","PREIS").into(FAHRZEUGE_JOIN.FAHRZEUGE_PREIS);
         from("FARBE");
         innerJoin("MODELLE",getColumn("MODELLE","ID").eq(getColumn("FAHRZEUGE","MODELL_ID")));
         innerJoin("HERSTELLER",getColumn("HERSTELLER","ID").eq(getColumn("MODELLE","HERSTELLER_ID")));
         
         setVirtualTable(FAHRZEUGE_JOIN.VT);
         setFillMethod(VirtualTableFillMethod.OVERWRITE);
      }
   }