Join über mehrere Tabellen
Maik W. aus E.
- datenbank
0 jobo0 Maik W. aus E.0 jobo
0 EKKi0 Ilja
Tach zusammen,
ich habe hier eine mySQL-DB (4.1.15 auf dem Testserver, 5.0.32 produktiv), in der ich drei Tabellen habe:
arztdaten
arzt_id| Daten | Daten | Daten...
history
history_id | ... | history_text
arzt_hi (verknüpft n:m arztdaten und history)
arzt_ref| history_ref
Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.
was ich habe:
SELECT ahi1.arzt_ref, ahi1.history_ref, h1.historytext, ahi2.arzt_ref, ahi2.history_ref, h2.historytext
FROM arzt_hi AS ahi1, history AS h1, history AS h2
INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
WHERE ahi1.history_ref = h1.historyid
AND h1.historytext LIKE 'Initialanschreiben erhalten'
AND ahi2.history_ref = h2.historyid
AND h2.historytext NOT LIKE 'Rückmeldung'
GROUP BY ahi1.arzt_ref
ORDER BY ahi1.arzt_ref
Aber irgendwie kommt da noch zu viel raus, nämlich alles. Kann wer helfen?
Danke
Maik
Hallo Maik,
ich weiß nur, dass Vinzenz immer wieder frustriert ist, wenn man trotz Lektüre seines dataillierten Howtos das nicht hinbekommt (;-). Das hast Du sicher gelesen hier bei selfhtml, oder?
Kleiner blöder Tipp am Rande: reduzier doch Dein Problem mal nur auf den Join und fange vielleicht mit zwei Tabellen an, ohne AS und SORT und soweiter.
Gruß
jobo
Tach auch jobo,
ich weiß nur, dass Vinzenz immer wieder frustriert ist, wenn man trotz Lektüre seines dataillierten Howtos das nicht hinbekommt (;-). Das hast Du sicher gelesen hier bei selfhtml, oder?
Ja sicher, sonst wäre ich ja gar nicht erst so weit gekommen...
Kleiner blöder Tipp am Rande: reduzier doch Dein Problem mal nur auf den Join und fange vielleicht mit zwei Tabellen an, ohne AS und SORT und soweiter.
Ähh, ohne AS und so würde der Join nicht im Ansatz funktionieren, weil ich ja zweimal auf die gleiche Tabelle zupacken muß...
Maik
Hallo,
Ähh, ohne AS und so würde der Join nicht im Ansatz funktionieren, weil ich ja zweimal auf die gleiche Tabelle zupacken muß...
Naja, ich hatte schon befürchtet, dass Du da schon Meilen voraus bist meinem Kenntnisstand (;-). Also auf Vinzenz warten.
Gruß
jobo
Mahlzeit Maik W. aus E.,
was ich habe:
SELECT ahi1.arzt_ref, ahi1.history_ref, h1.historytext, ahi2.arzt_ref, ahi2.history_ref, h2.historytext
FROM arzt_hi AS ahi1, history AS h1, history AS h2
INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
WHERE ahi1.history_ref = h1.historyid
AND h1.historytext LIKE 'Initialanschreiben erhalten'
AND ahi2.history_ref = h2.historyid
AND h2.historytext NOT LIKE 'Rückmeldung'
GROUP BY ahi1.arzt_ref
ORDER BY ahi1.arzt_ref
Du solltest zuerst diese Abfrage bereinigen - eine Mischform von expliziten und impliziten JOINs ist eigentlich nie wirklich sinnvoll, übersichtlich und verständlich. Vorschlag:
~~~sql
SELECT ahi1.arzt_ref
, ahi1.history_ref
, h1.historytext
, ahi2.arzt_ref
, ahi2.history_ref
, h2.historytext
FROM arzt_hi AS ahi1
INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
JOIN history AS h1 ON ahi1.history_ref = h1.historyid
JOIN history AS h2 ON ahi2.history_ref = h2.historyid
WHERE h1.historytext LIKE 'Initialanschreiben erhalten'
AND h2.historytext NOT LIKE 'Rückmeldung'
GROUP BY ahi1.arzt_ref
ORDER BY ahi1.arzt_ref
Zuerst einmal ist diese Abfrage unsauber, da Du lediglich über eine Spalte gruppierst, Dir aber weitere zusätzliche Spalten ohne passende Aggrgatsfunktion ausgeben lässt. Jedes andere DBMS außer MySQL würde Dir die Abfrage wieder um die Ohren hauen - und selbst MySQL muss raten, was Du haben willst ... es gibt keine Garantie dafür, dass das immer die gleichen Daten sind. Behebe also diesen Fehler.
Warum hast Du jetzt eine zweite Verknüpfungstabelle (ahi2) zur ersten (ahi1) dazugejoint? Warum joinst Du jeweils eine History-Tabelle zu jeder der beiden Verknüpfungstabellen?
Deine Anforderung war:
Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.
Du sprichst von *DER* zugehörigen History - benutzt aber zwei. Irgendwie ist mir das Datenmodell und das, was Du willst, noch nicht so ganz klar.
Aber irgendwie kommt da noch zu viel raus, nämlich alles. Kann wer helfen?
Definiere Deine Anforderungen genauer.
MfG,
EKKi
Tach auch Ekki,
Danke für Deine Rückmeldung.
SELECT ahi1.arzt_ref
, ahi1.history_ref
, h1.historytext
, ahi2.arzt_ref
, ahi2.history_ref
, h2.historytext
FROM arzt_hi AS ahi1
INNER JOIN arzt_hi AS ahi2 ON ahi1.arzt_ref = ahi2.arzt_ref
JOIN history AS h1 ON ahi1.history_ref = h1.historyid
JOIN history AS h2 ON ahi2.history_ref = h2.historyid
WHERE h1.historytext LIKE 'Initialanschreiben erhalten'
AND h2.historytext NOT LIKE 'Rückmeldung'
GROUP BY ahi1.arzt_ref
ORDER BY ahi1.arzt_ref
> Zuerst einmal ist diese Abfrage unsauber, da Du lediglich über eine Spalte gruppierst, Dir aber weitere zusätzliche Spalten ohne passende Aggrgatsfunktion ausgeben lässt. Jedes andere DBMS außer MySQL würde Dir die Abfrage wieder um die Ohren hauen -
ich weiß, ich weiß... habe das gemacht, um zu sehen, ob ich ansatzweise in die richtige Richtung tüftle.
> Warum hast Du jetzt eine zweite Verknüpfungstabelle (ahi2) zur ersten (ahi1) dazugejoint? Warum joinst Du jeweils eine History-Tabelle zu jeder der beiden Verknüpfungstabellen?
>
> Deine Anforderung war:
>
> > Jetzt möchte ich eine Liste aller arzt\_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.
>
> Du sprichst von \*DER\* zugehörigen History - benutzt aber zwei.
Ich dachte, daß ich ja zwei Abfragen brauche, einmal ob ein Wert "Initialanschreiben" da ist und einmal ob ein Wert "Rückmeldung" nicht da ist.
> Irgendwie ist mir das Datenmodell und das, was Du willst, noch nicht so ganz klar.
Kein Problem, also:
history:
id | history\_text
1 | Initialanschreiben erhalten
2 | Initialanschreiben erhalten
3 | Rückmeldung
arzt\_hi:
arzt\_ref | history\_ref
1 | 1
2 | 2
1 | 3
In der History-Tabelle werden alle Einträge für alle Ärzte gespeichert, die Verknüpfung auf die Arzt-Id wird über die arzt\_hi gelöst. Jetzt möchte ich die IDs der Ärzte, die einen "Initialanschreiben"-Eintrag haben, aber nicht "Rückmeldung", hier als Beispiel die ID '2'
> Definiere Deine Anforderungen genauer.
Besser?
Gruß
Maik
--

Mehr margin! Sag ich ja immer...
moin,
ich habe hier eine mySQL-DB (4.1.15 auf dem Testserver, 5.0.32 produktiv), in der ich drei Tabellen habe:
wenn möglich versuche beides auf die gleiche version zu bringen. kann zu überraschungen im unterschiedlichen verhalten führen.
Jetzt möchte ich eine Liste aller arzt_ids und ein paar Daten, bei denen in der zugehörigen History ein bestimmter History-Text steht und ein bestimmter andere eben nicht.
mal von deiner impliziter JOIN schreibweise abgesehen, auf die du schon hingewiesen wurdest, sind JOINS in vielen fällen "böse". das kommt aber immer auf die jeweilige verwendung drauf an. wenn du nur daten aus der tabelle arztdaten in der projektion ausgeben willst, dann solltest du JOINS vermeiden und korrelierte unterabfragen zum einsatz kommen lassen, die in die WHERE klausel eingebaut werden, um die gewünschten datensätze zu selektieren.
SELECT a.arzt_id, a.spalte2, a.spalte2....
FROM arztdaten a
WHERE EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Initialanschreiben erhalten'
)
AND NOT EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Rückmeldung'
)
;
Ilja
Tach auch Ilja,
wenn du nur daten aus der tabelle arztdaten in der projektion ausgeben willst, dann solltest du JOINS vermeiden und korrelierte unterabfragen zum einsatz kommen lassen, die in die WHERE klausel eingebaut werden, um die gewünschten datensätze zu selektieren.
Sehr elegante Lösung! Très chic!
SELECT a.arzt_id, a.spalte2, a.spalte2....
FROM arztdaten a
WHERE EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Initialanschreiben erhalten'
)
AND NOT EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Rückmeldung'
)
;
Jo, das klappt, wieder was gelernt, Besten Dank!
Maik
Hallo Ilja.
SELECT a.arzt_id, a.spalte2, a.spalte2....
FROM arztdaten a
WHERE EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Initialanschreiben erhalten'
)
AND NOT EXISTS (SELECT NULL
FROM arzt_hi ah
INNER JOIN history h ON h.history_id = ah.history_ref
WHERE ah.arzt_ref = a.arzt_id
AND h.historytext = 'Rückmeldung'
)
;
Hast du eine Buchempfehlung oder ein paar gute Internetseiten wo man sich sollche SQL-Techniken beibringen kann, abgesehen von der umfangreichen offiziellen Doku?
Lieben Gruß,
John
moin,
Hast du eine Buchempfehlung oder ein paar gute Internetseiten wo man sich sollche SQL-Techniken beibringen kann, abgesehen von der umfangreichen offiziellen Doku?
hmm, in den meisten büchern ist sql ist immer nur ein teil vom gesamtthema datenbanken und dann oftmals auch nur die basics, was sql betrifft. inner aller regel geht das nicht über joins hinaus. ich kenne eigentlich so aus dem stehgreif kein buch, was sich ein wenig intensiver mit sql abfragen beschäftigt. meines ertes buch war "SQL, der schlüssel zu relationalen datenbanken", aber auch dort gilt oben genanntes.
vielleicht das buch "advanced SQL" von daniel warner, das gab (gibt ?) es für lau bei terrrashop oder amazon.de, dort sind wengitens korrelierte unterabfragen mal aufgeführt. aber auch dort geht es nicht nur um sql und nicht mit allem was dort steht, mit dem bin ich zufrieden.
ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.
Ilja
Tach auch Ilja,
ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.
Woran lag's? Könnte es in Zukunft dazu kommen? Also ich fände es klasse, wenn Dein Wissen hier strukturiert erläutert würde, und man nicht die Erkenntnis nehmen und in Nachhinein zusammenstöppeln müßte. Ich gebe Dir gerne das Template für einen Artikel...
Grüße
Maik
moin,
»» ich wollte hier auch mal einen beitrag zum thema datenbanken bei selfhtml schreiben, aber dazu kam es nicht.
Woran lag's?
ganz genau kann ich das auch nicht sagen, allerdings haben hier schon kompetende menschen einen artikel über datenbanken geschrieben.
Ilja
Hallo,
ganz genau kann ich das auch nicht sagen, allerdings haben hier schon kompetende menschen einen artikel über datenbanken geschrieben.
Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )
Gruß
jobo
moin,
Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )
es geht weniger um beiträge im forum, sondern eher um artikel wie diese hier:
http://aktuell.de.selfhtml.org/artikel/datenbanken/
Ilja
Hallo,
moin,
»» Ich dachte, Vinzenz hätte. (http://forum.de.selfhtml.org/archiv/2008/8/t176055/#m1158145), da war Ilja ja mit dabei (;-). )
es geht weniger um beiträge im forum, sondern eher um artikel wie diese hier:
Natürlich, darauf bezieht sich Vinzenz ja in o.g. Link:
"wenn es irgendwo vom Verständnis hakt, wäre ich Dir für eine Rückmeldung dankbar. Mein Artikel ist zwar seit über zwei Jahren unverändert, aber das heißt nicht, dass er nicht verbessert werden kann. Für den Autor ist es oft sehr schwer nachzuvollziehen, wo der Leser hängenbleibt, wo ein zu großer Sprung ist, wo etwas nicht exakt genug erklärt ist, ..."
Gruß
jobo
moin,
Natürlich, darauf bezieht sich Vinzenz ja in o.g. Link:
und wie kommmst du dann darauf, dass ich mit dabei war ? meine mitarbeit an den beiträgen war meiner meinung nach nicht erwünscht, aber die genauen hintergründe kenne ich nicht.
Ilja
Hallo,
und wie kommmst du dann darauf, dass ich mit dabei war ? meine mitarbeit an den beiträgen war meiner meinung nach nicht erwünscht, aber die genauen hintergründe kenne ich nicht.
Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.
Gruß
jobo
moin,
Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.
hier sind sicherlich einige threads mit meiner beteiligung. aber ich hatte dir schon probiert klar zu machen, dass es nicht um die beiträge hier im forum geht, sondern um ganz autarke artikel, was du als Doku bezeichnest. damals hatte ich vorgeschlagen, einen solchen zu schreiben, aber man wollte das wohl nicht.
Ilja
Hallo,
moin,
»» Bei dem Thread war doch auch ein Ilja, nicht bei der Doku.
hier sind sicherlich einige threads mit meiner beteiligung. aber ich hatte dir schon probiert klar zu machen, dass es nicht um die beiträge hier im forum geht, sondern um ganz autarke artikel, was du als Doku bezeichnest. damals hatte ich vorgeschlagen, einen solchen zu schreiben, aber man wollte das wohl nicht.
doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.
Gruß
jobo
moin,
doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.
du kennst vielleicht dir hintergründe nicht, aber ich wiederhole es gerne noch mal. ich denke nicht, dass meine mitarbeit an den artikeln erwünscht ist.
Ilja
Hallo,
moin,
»» doch, habe ich schon kapiert. vinzenz bat ja darum, seinen artikel zu überarbeiten, um das verständnis zu erhöhen.
du kennst vielleicht dir hintergründe nicht, aber ich wiederhole es gerne noch mal. ich denke nicht, dass meine mitarbeit an den artikeln erwünscht ist.
Ja, hatte ich schon verstanden.
Gruß
jobo