AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi SQL | INNER JOINS über mehrere Tabellen

SQL | INNER JOINS über mehrere Tabellen

Ein Thema von f4k3 · begonnen am 9. Jun 2009 · letzter Beitrag vom 15. Jun 2009
Antwort Antwort
Seite 1 von 2  1 2   
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#1

SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 10:43
Datenbank: Firebird • Version: 2.1 • Zugriff über: ZEOS
Moin Moin liebe DPler

hab mal ne Frage ... und zwar hab ich ne Abfrage gemacht die mir sämlichste Informationen über
einen "Kontakt" holt.

Ich bekommen einen Dynamic SQL Error SQL error code = -204

Also hab ich mir auf der Firebird Seite die Firebird 2.1 Error Codes angekuckt ... nur kommen da leider mehrere Ursachen in Frage ... und ich komm einfach nicht drauf...

Vielleicht sieht jemand mit seinem geschulten Auge den Fehler ...

Das ist mein Code ...
SQL-Code:
SELECT
    k.KON_ID, k.KONTAKTART_ID, k.VORNAME as firstname, k.NACHNAME as lastname,
    k.FIRMA as company, k.ANGELEGT, k.GEAENDERT,
    
    kk.KON_KONTAKTART_ID, kk.BEZEICHNUNG, kk.BESCHREIBUNG,
    
    kt.KON_TELEFON_ID, kt.KONTAKT_ID, kt.KONTAKTART_ID, kt.ANSPRECHPARTNER as contact,
    kt.RUFNUMMER as phone,
    
    kabt.KON_ABTEILUNG_ID, kabt.ABTEILUNG,
    
    kasp.KON_ANSPRECHPARTNER_ID, kasp.KONTAKT_ID, kasp.ABTEILUNG_ID,
    kasp.VORNAME, kasp.NACHNAME

FROM KON_TELEFON kt

  INNER JOIN KON k
    ON (kt.KONTAKT_ID = k.KON_ID)
  INNER JOIN KON_KONTAKTART kk
    ON (k.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
  INNER JOIN KON_KONTAKTART kk
    ON (kt.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
  INNER JOIN KON_ABTEILUNG kabt
    ON ((kasp.ABTEILUNG_ID = kabt.KON_ABTEILUNG_ID))
  INNER JOIN KON_ANSPRECHPARTNER kasp
    ON (kasp.KONTAKT_ID = k.KON_ID)
  
WHERE kt.RUFNUMMER = '123'
Das natürlich nur ein Testcode

Vielen dank für eure Posts

Euer f4k3

[b]//edit: Beim Öffnen des Links kann es passieren, da das Dokument im PDF-Format vorliegt, dass es ziemlich lange
dauert bis es geöffnet ist ... Größe des Dokuments ~ 104 Kb ... nur so als kleine Info am Rande
Sascha
  Mit Zitat antworten Zitat
Leonard

Registriert seit: 12. Okt 2005
Ort: Lutherstadt Eisleben
64 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:13
Hallo,

Zitat von f4k3:
SQL-Code:
  INNER JOIN KON_KONTAKTART kk
    ON (k.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
  INNER JOIN KON_KONTAKTART kk
    ON (kt.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
ich würde sagen in deinem Fall ist es ein alias_conflict_err, da du den Tabellenalias kk 2-mal verwendest.
Tobias
  Mit Zitat antworten Zitat
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#3

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:14
Zitat von Leonard:
Hallo,

Zitat von f4k3:
SQL-Code:
  INNER JOIN KON_KONTAKTART kk
    ON (k.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
  INNER JOIN KON_KONTAKTART kk
    ON (kt.KONTAKTART_ID = kk.KON_KONTAKTART_ID)
ich würde sagen in deinem Fall ist es ein alias_conflict_err, da du den Tabellenalias kk 2-mal verwendest.
mhm ... dat is schlecht ... weil ich beide Prüfungen brauche ...
aber JOINS lassen sich bestimmt mit AND, OR, XOR verknüpfen oder?

Dann könnte ich es ja so lösen ...
Sascha
  Mit Zitat antworten Zitat
Leonard

Registriert seit: 12. Okt 2005
Ort: Lutherstadt Eisleben
64 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:28
Zitat von f4k3:
mhm ... dat is schlecht ... weil ich beide Prüfungen brauche ...
aber JOINS lassen sich bestimmt mit AND, OR, XOR verknüpfen oder?
Das sollte gehen. Kann es aber auch sein, dass in k.KON_KONTAKTART_ID und kt.KON_KONTAKTART_ID die gleichen Werte stehen?

Noch etwas anderes ist mir jetzt aufgefallen. Es kann auch noch sein, dass du die letzten beiden INNER JOIN Anweisungen tauschen musst. Die Verknüpfung zu kasp wird erst in der letzten Anweisung erstellt, aber schon in der vorherigen verwendet. Es kann aber sein, dass Firebird das so kann.

Alt:
SQL-Code:
INNER JOIN KON_ABTEILUNG kabt ON (kasp.ABTEILUNG_ID = kabt.KON_ABTEILUNG_ID)
INNER JOIN KON_ANSPRECHPARTNER kasp ON (kasp.KONTAKT_ID = k.KON_ID)

Neu:
SQL-Code:
INNER JOIN KON_ANSPRECHPARTNER kasp ON (kasp.KONTAKT_ID = k.KON_ID)
INNER JOIN KON_ABTEILUNG kabt ON (kasp.ABTEILUNG_ID = kabt.KON_ABTEILUNG_ID)
Tobias
  Mit Zitat antworten Zitat
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#5

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:44
Zitat von Leonard:
Zitat von f4k3:
mhm ... dat is schlecht ... weil ich beide Prüfungen brauche ...
aber JOINS lassen sich bestimmt mit AND, OR, XOR verknüpfen oder?
Das sollte gehen. Kann es aber auch sein, dass in k.KON_KONTAKTART_ID und kt.KON_KONTAKTART_ID die gleichen Werte stehen?

Noch etwas anderes ist mir jetzt aufgefallen. Es kann auch noch sein, dass du die letzten beiden INNER JOIN Anweisungen tauschen musst. Die Verknüpfung zu kasp wird erst in der letzten Anweisung erstellt, aber schon in der vorherigen verwendet. Es kann aber sein, dass Firebird das so kann.

Alt:
SQL-Code:
INNER JOIN KON_ABTEILUNG kabt ON (kasp.ABTEILUNG_ID = kabt.KON_ABTEILUNG_ID)
INNER JOIN KON_ANSPRECHPARTNER kasp ON (kasp.KONTAKT_ID = k.KON_ID)

Neu:
SQL-Code:
INNER JOIN KON_ANSPRECHPARTNER kasp ON (kasp.KONTAKT_ID = k.KON_ID)
INNER JOIN KON_ABTEILUNG kabt ON (kasp.ABTEILUNG_ID = kabt.KON_ABTEILUNG_ID)
Alles klar ... Die alte Variante funktioniert aber auch ... habs in Database Workbench 3 Lite for Firebird getestet.

Mir is nur n kleiner Fehler unterlaufen ... also ich möchte ja nur die Informationen zu einem bestimmten Kontakt.
und ich hab 8 Tabellen für meine Kontaktverwaltung (kommen später noch mehr) ... Es ist aber keine notwendigkeit dass
in allen Tabellen Informationen zum Kontakt vorhanden sein müssen. Wenn bei meiner Abfrage jedoch in einem JOIN kein
Datensatz gefunden wird ... ist der Kontakt auch nicht in der Ergebnismenge obwohl ich genau nach diesem Kontakt Suche ...

Muss ich dass dann mit einem OUTER JOIN lösen oder alle JOINS rausschmeissen und die Daten händisch abfragen? mit einer WHERE-Klausel?

Ich hab nämlich mein Lösungsansatz mal an ein paar Testdaten ausprobiert und bin drauf gestossen dass ich nach einem
Benutzer suche ... der aber nicht in der Ergebnismenge auftaucht obwohl er vorhanden ist, weil eben in 2 Tabellen die mit
JOINS abgefragt werden keine Werte zu diesem Nutzer enthalten sind ... wenn ich Werte einfüge wird der Benutzer angezeigt ...

Hier mal die Abfrage ...

SQL-Code:
SELECT

    // BEN
    b.BEN_ID, b.RECHTE_ID, b.ABTEILUNG_ID, b.BENUTZERNAME, b.PASSWORT,
    b.VORNAME, b.NACHNAME, b.GEBURTSTAG, b.EINSTELLUNGSDATUM, b.ENTLASSUNGSDATUM,
    b.EINGELOGGT,
    
    // BEN_ABTEILUNG
    bab.BEN_ABTEILUNG_ID, bab.ABTEILUNGSNAME,
    
    // BEN_ADRESSE
    bad.BEN_ADRESSE_ID, bad.BENUTZER_ID, bad.KONTAKTART_ID, bad.STRASSE,
    bad.POSTLEITZAHL, bad.ORT,
    
    // BEN_EMAIL
    be.BEN_EMAIL_ID, be.BENUTZER_ID, be.KONTAKTART_ID, be.EMAIL_ADRESSE,
    
    // BEN_KONTAKTART
    bk.BEN_KONTAKTART_ID, bk.BEZEICHNUNG, bk.BESCHREIBUNG,
    
    // BEN_NOTIZEN
    bn.BEN_NOTIZEN_ID, bn.BENUTZER_ID, bn.BEZEICHNUNG, bn.BESCHREIBUNG,
    bn.ANGELEGT, bn.GEAENDERT,
    
    // BEN_RECHTE
    br.BEN_RECHTE_ID, br.BEZEICHNUNG, br.ADMINISTRATOR,
    
    // BEN_TELEFON
    bt.BEN_TELEFON_ID, bt.BENUTZER_ID, bt.KONTAKTART_ID, bt.RUFNUMMER

FROM BEN b, BEN_KONTAKTART bk

    // INNER JOIN BEN_RECHTE
    INNER JOIN BEN_RECHTE br
      ON (b.RECHTE_ID = br.BEN_RECHTE_ID)
    
    // INNER JOIN BEN_ABTEILUNG
    INNER JOIN BEN_ABTEILUNG bab
      ON (b.ABTEILUNG_ID = bab.BEN_ABTEILUNG_ID)
    
    // INNER JOIN BEN_ADRESSE
    INNER JOIN BEN_ADRESSE bad
      ON (bad.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_EMAIL
    INNER JOIN BEN_EMAIL be
      ON (be.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_NOTIZEN
    INNER JOIN BEN_NOTIZEN bn
      ON (bn.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_TELEFON
    INNER JOIN BEN_TELEFON bt
      ON (bt.BENUTZER_ID = b.BEN_ID) AND (bt.KONTAKTART_ID = bk.BEN_KONTAKTART_ID)

WHERE b.BENUTZERNAME = 'Jonny'
MfG f4k3
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#6

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:48
Also hab grad gelesen dass ich es mit einem LEFT OUTER JOIN machen könnte.

Ich probier dass ganze mal aus
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#7

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 11:59
Also ich habs probiert

SQL-Abfrage ...

SQL-Code:
SELECT

    // BEN
    b.BEN_ID, b.RECHTE_ID, b.ABTEILUNG_ID, b.BENUTZERNAME, b.PASSWORT,
    b.VORNAME, b.NACHNAME, b.GEBURTSTAG, b.EINSTELLUNGSDATUM, b.ENTLASSUNGSDATUM,
    b.EINGELOGGT,
    
    // BEN_ABTEILUNG
    bab.BEN_ABTEILUNG_ID, bab.ABTEILUNGSNAME,
    
    // BEN_ADRESSE
    bad.BEN_ADRESSE_ID, bad.BENUTZER_ID, bad.KONTAKTART_ID, bad.STRASSE,
    bad.POSTLEITZAHL, bad.ORT,
    
    // BEN_EMAIL
    be.BEN_EMAIL_ID, be.BENUTZER_ID, be.KONTAKTART_ID, be.EMAIL_ADRESSE,
    
    // BEN_KONTAKTART
    bk.BEN_KONTAKTART_ID, bk.BEZEICHNUNG, bk.BESCHREIBUNG,
    
    // BEN_NOTIZEN
    bn.BEN_NOTIZEN_ID, bn.BENUTZER_ID, bn.BEZEICHNUNG, bn.BESCHREIBUNG,
    bn.ANGELEGT, bn.GEAENDERT,
    
    // BEN_RECHTE
    br.BEN_RECHTE_ID, br.BEZEICHNUNG, br.ADMINISTRATOR,
    
    // BEN_TELEFON
    bt.BEN_TELEFON_ID, bt.BENUTZER_ID, bt.KONTAKTART_ID, bt.RUFNUMMER

FROM BEN b, BEN_KONTAKTART bk

    // INNER JOIN BEN_RECHTE
    LEFT OUTER JOIN BEN_RECHTE br
      ON (br.BEN_RECHTE_ID = b.RECHTE_ID)
    
    // INNER JOIN BEN_ABTEILUNG
    LEFT OUTER JOIN BEN_ABTEILUNG bab
      ON (bab.BEN_ABTEILUNG_ID = b.ABTEILUNG_ID)
    
    // INNER JOIN BEN_ADRESSE
    LEFT OUTER JOIN BEN_ADRESSE bad
      ON (bad.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_EMAIL
    LEFT OUTER JOIN BEN_EMAIL be
      ON (be.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_NOTIZEN
    LEFT OUTER JOIN BEN_NOTIZEN bn
      ON (bn.BENUTZER_ID = b.BEN_ID)
    
    // INNER JOIN BEN_TELEFON
    LEFT OUTER JOIN BEN_TELEFON bt
      ON (bt.BENUTZER_ID = b.BEN_ID) AND (bt.KONTAKTART_ID = bk.BEN_KONTAKTART_ID)

WHERE b.BENUTZERNAME = 'Jonny'
Als Ergebnis bekomme ich zwar keinen Fehler ... aber eine Informatione "no current record for fetch operation" was soviel heißt wie kein Datensatz für fetch-operation verfügbar, wenn mich mein Englisch nicht im stich lässt

Bis auf BEN_NOTIZEN enthalten aber alle Tabellen Informationen die mit dem Benutzer verknüpft sind ...
Und so wie ich den LEFT OUTER JOIN verstanden habe ... müssten alle Daten geliefert werden zu denen eine Verknüpfung existiert

Oder hab ich das Prinzip nicht ganz verstanden?

MfG f4k3
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 12:08
Bekommst Du ein Ergebnis, wenn Du die ganzen Joins und damit verbundenen Tabellen/Felder weglässt? Vielleicht war es nur ein Tippfehler und es existiert gar kein solcher Benutzer in der Haupttabelle.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von f4k3
f4k3

Registriert seit: 15. Aug 2007
Ort: Nürnberg
313 Beiträge
 
Delphi 2007 Architect
 
#9

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 12:15
Zitat von DeddyH:
Bekommst Du ein Ergebnis, wenn Du die ganzen Joins und damit verbundenen Tabellen/Felder weglässt? Vielleicht war es nur ein Tippfehler und es existiert gar kein solcher Benutzer in der Haupttabelle.
Also wenn ich nur die Haupttabelle abfrage "BEN" dann bekomme ich die Informationen ... aber eben nur aus dieser einen
Tabelle ...

Aber ich glaub ich muss meine Normalisierung mal überdenken ... ich habs zwar noch nicht ausgiebig geprüft ... aber ich glaube
es gibt ein paar Unstimmigkeiten ...

Ein Benutzer kann zum Beispiel in BEN_EMAIL mehrere E-Mail-Adressen haben die wiederum unterteilt werden in eine KONTAKTART wie z.B: intern, privat. Die Tabelle BEN_EMAIL trägt also noch ein Feld "KONTAKTART_ID" dass auf die TABELLE BEN_KONTAKTART->BEN_KONTAKTART_ID verweist ...

vielleicht liegt darin der Fehler dass die einzelnen Tabellen teilweise auch noch mit anderen Tabellen verknüpft sind ...
Sascha
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.537 Beiträge
 
Delphi 11 Alexandria
 
#10

Re: SQL | INNER JOINS über mehrere Tabellen

  Alt 9. Jun 2009, 12:38
Dann hätte die Abfrage aber ein Ergebnis liefern müssen, wenn ich das richtig überschaut habe. Gibt es in den Detailtabellen keinen passenden Datensatz, enthalten die Felder bei einem OUTER JOIN dann NULL-Werte.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz