![]() |
Datenbank: dbase • Zugriff über: BDE
Problem mit mehrfachen JOIN
Hi NG.
Ich möchte per localSQL eine Abfrage über vier Tabellen tab1, tab2, tab3 und tab4 erstellen. Die Beziehungen der Tabellen untereinander sind wie folgt:
Delphi-Quellcode:
Das Query soll alle Sätze aus tab1 anzeigen.
tab4 <- tab1 -> tab2 -> tab3
mit -> := OUTER JOIN Bisher schaut meine Abfrage so aus:
SQL-Code:
Als Ergebnis erhalte ich hierbei mehr Sätze als erwartet.
SELECT tab1.FeldA, tab2.FeldB, tab3.FeldC, tab4.FeldD
FROM tab1 LEFT OUTER JOIN tab2 ON (tab1.Feld1=tab2.Feld1) AND (tab1.Feld2=tab2.Feld2) LEFT OUTER JOIN tab3 ON (tab2.Feld3=tab3.Feld3) LEFT OUTER JOIN tab4 ON (tab1.Feld4=tab4.Feld4) WHERE (tab2.Feld5 IS NULL OR tab2.Feld5=100) OR tab3.Feld7 IS NULL AND (tab4.Feld6 IS NULL OR tab4.Feld6=100) Lasse ich im SQL-Text die JOIN-Zeile von tab4 weg, so erhalte ich die korrekte Anzahl an Sätzen. Kann mir jemand einen Tipp geben was ich falsch mache? Gruß Peter |
Re: Problem mit mehrfachen JOIN
Hi,
mir ist aufgefallen, dass du noch zwei Klammern vergessen hast.
SQL-Code:
Bin mir aber nicht sicher ob es das Problem löst................... :oops:
SELECT tab1.FeldA, tab2.FeldB, tab3.FeldC, tab4.FeldD
FROM tab1 LEFT OUTER JOIN tab2 ON ((tab1.Feld1=tab2.Feld1) AND (tab1.Feld2=tab2.Feld2)) LEFT OUTER JOIN tab3 ON (tab2.Feld3=tab3.Feld3) LEFT OUTER JOIN tab4 ON (tab1.Feld4=tab4.Feld4) WHERE (tab2.Feld5 IS NULL OR tab2.Feld5=100) OR tab3.Feld7 IS NULL AND (tab4.Feld6 IS NULL OR tab4.Feld6=100) Grüße.................. :dance: |
Re: Problem mit mehrfachen JOIN
Leider löst das das Problem auch nicht.
Es zeigt sich über keine Veränderung mit oder ohne diesen Klammern. |
Re: Problem mit mehrfachen JOIN
Muss das nicht vllt. so aussehen:
SQL-Code:
Das Problem iss dass ich fast aussließlich unter ORACLE programmiere. Zwar ab und zu auch unter MSSQl oder DB2(gleiche schreibweise wie in deinem Beispiel) aber da verzweifel ich auch immer an den Outer joins............und frag dann immer lieber nen Arbeitskollegen und lass ihn drüber gucken............
SELECT tab1.FeldA, tab2.FeldB, tab3.FeldC, tab4.FeldD
FROM tab1 LEFT OUTER JOIN tab2 ON ((tab1.Feld1=tab2.Feld1) AND (tab1.Feld2=tab2.Feld2)), tab2 LEFT OUTER JOIN tab3 ON (tab2.Feld3=tab3.Feld3), tab1 LEFT OUTER JOIN tab4 ON (tab1.Feld4=tab4.Feld4) WHERE (tab2.Feld5 IS NULL OR tab2.Feld5=100) OR tab3.Feld7 IS NULL AND (tab4.Feld6 IS NULL OR tab4.Feld6=100) Güße............ |
Re: Problem mit mehrfachen JOIN
Mir fällt gerade etwas noch seltsameres auf.
Wenn ich alle vier Tabellen mit JOIN verknüpfe wie beschrieben, so werden mir Nonsens-Daten angezeigt. Irgendwie sind die dargestellten Werte verrutscht. Mit verrutscht meine ich, dass die in den einzelnen Ausgabefeldern Daten aus mehreren Feldern zusammen angezeigt werden und diese z.T. noch verstümmelt. Ganz seltsam! Entferne ich aus der Abfrage tab4, so wird alles korrekt ausgeführt und dargestellt - wie bereits erwähnt. |
Re: Problem mit mehrfachen JOIN
@zwaem86
Das sieht auch recht sympatisch aus ;), aber es bringt Borlands DBoberfläche zum Absturz. Aber ich glaube auch nicht, dass deine Variante nötig ist, da es ja auch so nur mit den drei tab1..3 klappt. |
Re: Problem mit mehrfachen JOIN
Hallo Peter,
deine WHERE Klausel sieht mir nicht ganz koscher aus. Ich würde eine AND Verknüpfung an der bezeichneten Stelle erwarten:
SQL-Code:
Grüße vom marabu
SELECT tab1.FeldA, tab2.FeldB, tab3.FeldC, tab4.FeldD
FROM tab4 RIGHT OUTER JOIN tab1 ON tab1.Feld4 = tab4.Feld4 LEFT OUTER JOIN tab2 ON tab1.Feld1 = tab2.Feld1 AND tab1.Feld2 = tab2.Feld2 LEFT OUTER JOIN tab3 ON tab2.Feld3 = tab3.Feld3 WHERE (tab4.Feld6 IS NULL OR tab4.Feld6=100) AND (tab2.Feld5 IS NULL OR tab2.Feld5=100) AND tab3.Feld7 IS NULL /* AND statt OR ? */ |
Re: Problem mit mehrfachen JOIN
Zitat:
Schonmal ohne Where-Klausel probiert? |
Re: Problem mit mehrfachen JOIN
Nein, das tab2 muss schon sein. Die Beziehung ist ja "tab2->tab3" und nicht "tab1->tab3". Bitte nicht verwechseln mit dem mathematischen Folgerungsschluss "A->B und B->C dann auch A->C".
Wenn ich die WHERE-Klausel weglasse, werden mir nicht alle Sätze von tab1 angezeigt. Das muss schon so sein. |
Re: Problem mit mehrfachen JOIN
Hallo Peter,
wie ist deine Antwort auf die Frage AND statt OR aus Beitrag #7? Freundliche Grüße marabu |
Re: Problem mit mehrfachen JOIN
Sorry für meine verspätete Antwort.
So, ich habe mir den SQL Text und das Resultat nochmals angeschaut und festgestellt, dass die Abfrage ausschließlich mit den tab1..3 nicht korrekt funktioniert - entgegen meiner vorherigen Behauptungen. Die Anzahl der Sätze dort ist auch nicht richtig. Die Beziehungen der Tabellen untereinander möchte ich nochmals anders darstellen. Vielleicht hilft das.
SQL-Code:
Mir hat jemand den Tipp gegeben, in der WHERE-Klausel auf die IS NULL Bedingungen zu verzichten und die fehlenden Sätze stattdessen mit UNION-Verbindungen zu ergänzen. Das ganze scheint mir recht kompliziert zu sein. Ich werde es mir jetzt als nächstes mal anschauen.
tab1 n:1 tab2
tab2 n:1 tab3 tab1 n:1 tab4 Aus meinen bisherigen Versuchen vermute ich, dass die von mir gedachte Abfrage tatsächlich nicht möglich ist. Interessieren würde mich jetzt aber schon warum? Gruß Peter |
Re: Problem mit mehrfachen JOIN
Hallo PASST,
vielleicht kannst du uns ja mal erklären was du eigentlich machen bzw. als Ergebnis herausbekommen möchtest. Das du mehr Datensätze herausbekommst als in Tab1 enthalten sind ist doch klar. Wenn in einer der anderen Tabellen auf mehr als einen Datensatz in Tab1 verwiesen wird, muss der entsprechende Datensatz aus Tab1 mehrfach ausgegeben werden. Vielleicht kannst du ja mal genau schreiben was du eigentlich haben möchtest, ich konnte das bis jetzt noch nicht erkennen. Gruss Thorsten |
Re: Problem mit mehrfachen JOIN
So, jetzt kann ich endlich antworten.
Vorab folgende Info: Ich habe festgestellt, dass wider Erwarten die Beziehung von tab1 zu tab2 n:m war. Ich habe tab2 jetzt bearbeitet, so dass tatsächlich eine n:1 Beziehung zw. tab1 und tab2 besteht. Was will ich eigentlich konkret? Ich will eine Schnittstelle schreiben, die es erlaubt eine Einkaufsdatei vom Lieferanten mit unseren Artikelnamen zu ergänzen. Die Einkaufsdatei ist tab1 und die Übersetzungsdatei für unsere Artikel ist tab2. Da in der Einkaufsdatei ein Artikel mehrfach eingetragen sein kann, aber es je Position nur eine Artikelzuordnung geben kann, ist die Beziehung zw. tab1 und tab2 n:1. Ich möchte also zu jeder Einkaufsposition unseren Artikelnamen anzeigen. Ist noch keine Artikelzuordnung vorhanden, so soll mir die Einkaufsposition trotzdem angezeigt werden. (tab3 und tab4 lasse ich erstmal außer acht.)
SQL-Code:
Im Detail habe ich für die Artikelzuordnung zwei Kriterien, was aber keinen Unterschied machen sollte.
SELECT tab1.FeldA, tab2.FeldB, tab3.FeldC, tab4.FeldD
FROM tab1 LEFT OUTER JOIN tab2 ON (tab1.Feld1=tab2.Feld1) AND (tab1.Feld2=tab2.Feld2) WHERE (tab2.Feld5 IS NULL OR tab2.Feld5=100) Verwende ich nur das WHERE-Kriterium =100, dann erhalte ich korrekterweise nur die Einkaufspositionen für die eine Artikelnamenzuordnung existiert. Verwende ich beide Kriterien, so erhalte ich aber immer noch weniger Einkaufsposition wie vorhanden sind. Insgesamt fehlen 3 Stück. Gruß Peter |
Re: Problem mit mehrfachen JOIN
Hallo PASST,
versuch es doch mal so...
SQL-Code:
eventuell kennt dbase COALESCE nicht...
SELECT t1.FeldA, t2.FeldB
FROM tab1 t1 LEFT JOIN tab2 t2 ON t1.Feld1 = t2.Feld1 AND t1.Feld2 = t2.Feld2 AND COALESCE(t2.Feld5, 100) = 100
SQL-Code:
Gruss
SELECT t1.FeldA, t2.FeldB
FROM tab1 t1 LEFT JOIN tab2 t2 ON t1.Feld1 = t2.Feld1 AND t1.Feld2 = t2.Feld2 AND ( t2.Feld5 IS NULL OR t2.Feld5 = 100) Thorsten |
Re: Problem mit mehrfachen JOIN
Bin gerade zuhaus und habe leider kein Delphi zur Hand. Ich werde das ganze mir morgen auf der Arbeit anschauen.
Aber schon mal ein paar Kommentare. Soweit ich weiß, kann dbase tatsächlich kein Coalesce - aber nebenbei bemerkt, ist das hier nicht die Frage ob localSQL kein Coalesce kann? Die zweite Variante ist mir auch neu sie überhaupt so zu schreiben. Es schaut recht plausibel aus, sieht mir aber nach einer Syntaxvariante aus, die zum gleichen Ergebnis führt. Ich lass mich morgen mal überraschen. Ich bin für weitere Vorschläge offen :) Peter |
Re: Problem mit mehrfachen JOIN
Und nochmal ein bisken Senf dazu.
Ich befürchte, irgendwer oder irgendwas will mich hier ärgern. Ich habe jetzt versucht die gleiche Abfrage auf einem MS SQL Server 2000 nachzubilden. Ich habe ähnlich Daten genommen, für die aber in der LEFT OUTER JOIN Verknüpfung das selbe gelten MUSS. Ich habe eine Kundentabelle tKdn, jeder Kunden ist dort genau einmal aufgeführt, und eine Tabelle Aufträge tAuftr. Verknüpft sind beide über die Kundennr. Die Beziehung zw tKdn und tAuftr ist logischerweise 1:n. Ebenfalls hat nicht jeder Kunde Aufträge.
SQL-Code:
Dies sollte mir die Anzahl aller Kunden ausgeben. Als Ergebnis erhalte ich aber nur die Anzahl aller Kunden, für die ein Auftrag existiert. Und das ganze habe ich mit dem Query-Tool vom MS SQL Server gemacht -also kein BDE und localSQL.
select count(distinct kundnr)
from tKdn left outer join tAuftr on tKdn.kundnr=tAuftr.kundnr Ich habe den Verdacht, dass ich bzgl. OUTER JOIN irgendwas komplett falsch verstanden habe, obwohl alle Definitionen, die ich im Inet gefunden habe, meine bisherige Meinung bestätigen. Verzweiflung am eigenen Verstand macht sich langsam bei mir breit :( Peter |
Re: Problem mit mehrfachen JOIN
Also für die Anzahl der Kunden zu erhalten musst du doch nicht joinen:
SQL-Code:
select count(*) as Anzahl from tKdn
|
Re: Problem mit mehrfachen JOIN
Count war nur als Bsp gedacht.
|
Re: Problem mit mehrfachen JOIN
@omata (Beitrag #14)
Vielen Dank, deine zweite Variante, wenn auch ohne IS NULL, funktioniert. IS NULL wird ja durch das LEFT OUTER JOIN überflüssig. Jetzt wo ich weiß, dass es funktioniert, ist mir die Logik dahinter auch klar :) Die n:1-Beziehung zw. tab1 und tab2 gilt nur bei Verlinkung von Feld1, Feld2 UND Feld5. Verlinke ich nur Feld1 und 2, so erhalte ich (natürlich) mehr Kombinationen im Ergebnis. Argh! :oops: Danke nochmals an alle, die mir geholfen haben. Peter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz