mehrere Tabellen abfragen

kuroo

Grünschnabel
Hallo, ich bin neu hier, also als erstes schön euch kennen zulernen, ich bin Schüler (im BK Bereich Wirtschaft Informatik) und wir nehmen gerade das Thema Rationaler Datenbanken in der schule durch.


Nun habe ich aber ein kleines Problem mit einem Aufbau.
2014-07-19_171403.jpg

Ich möchte alle Kommentare ausgeben die zu Einem Artikel gehören,

dabei möchte ich folgende Daten haben

Kommentar. idKommentar, text, datum Account. idAcconunt, name


Aber so wie es uns unserer Lehre es erklärt hat, müsste ich nun erst in der Tabelle Kommentar_has_Artikel alle Kommentar_idKommentar auslesen und dann einzelnen abfragen starten um an die Daten in der Tabelle Kommentar ranzukommen und dann noch mall eine gesonderte Abfrage für die Daten in Account.


Das ist aber in meinen Augen fiel zu ineffektiv, geschweigenden was das für einen Aufwand ist.

Nun ist meine Frage, wie bekommt man das mit einer Abfrage hin?


Mfg. kuroo
 
Du sollst ja etwas lernen, daher bieten wir die Unterstützung an. Wie lautet dein Ansatz? Das Zauberwort lautet in deinem Fall JOIN. Probiers mal und sag' uns wie weit du gekommen bist.
 
oke danke für den Ansatz.

Das wehre mein Einfall dazu, aber in der Console wird es nicht ausgeführt.
Code:
SELECT Kommentar.idKommentar, text, datum Account.idAcconunt, name
FROM Kommentar_has_Artikel
JOIN Kommentar ON idKommentar = Kommentar_idKommentar 
JOIN Account ON idAccount = Account_idAccount
WHERE Artikel_idArtikel = 1
ORDER BY Kommentar.datum ASC;
 
Zuletzt bearbeitet:
Auf dem ersten Blick sieht es für mich nicht falsch aus, zeigt deine Konsole irgendwelche Fehlermeldungen an?

Auf dem zweiten Blick sieht die erste Zeile für mich jedoch merkwürdig aus. Ich bin mir nicht sicher, ob es - wie anscheinend gewollt - so automatisch interpretiert wird, dass 'text' und 'datum 'zu Kommentar und 'name' zu Account zugeordnet wird, ich bezweifle es sogar. Das System rät also an dieser Stelle welche Spalte gemeint ist. Da 'datum' sowohl in Kommentar als auch Account vorhanden ist gibt es vermutlich einen Fehler, da das System nicht weiß welche von beiden Spalten gemeint ist.

Ansonsten haben deine Tabellen ziemlich lange Namen, wenn du alle immer wieder verwendest bläht sich das Statement um Einiges auf. Tipp: Verwende kurze Aliase.
 
Zuletzt bearbeitet:
Na ja,

ergänzend zu HonniCilest:
Ganz falsch ist es nicht, aber...
- zwischen zwei Feldern in der SELECT-Liste fehlt ein Komma
- ein Feldname ist falsch geschrieben ("id_Acconunt")
- "text", "datum" und der eben genannte "id_Acconunt" können nicht eindeutig einer Tabelle zugeordnet werde, da ohne Alias
- und ein JOIN zwischen Tabelle "Artikel" und "Kommentar_hat_Artikel" fehlt.

Solte also eher in diese Richtung gehen:

SQL:
SELECT k.idKommentar, k.text, k.datum, acc.idAcconunt, acc.name
FROM Kommentar_has_Artikel kha
JOIN Kommentar k ON k.idKommentar = kha.Kommentar_idKommentar
JOIN Account acc ON acc.idAccount = k.Account_idAccount
JOIN Artikel art on art.idArtikel =kha.Artikel_idArtikel
WHERE Artikel.idArtikel = 1
ORDER BY k.datum ASC;

Tendentiell jedenfalls.

Ausdrücklich unterstreichen möchte ich den Hinweis auf die sich spiralförmig dahinwindenden Feldnamen.
So nimmst du dir die Lust an jedem Statement und allen Beteiligten die Chance auf jegliche Les- und Wartbarkeit.

Änderungsvorschlag:

- aus "Kommentar_idKommentar" wird eine "KommentarID", egal in welcher Tabelle
- aus "Artikel_idArtikel" wird eine "ArtikellD", egal in welcher Tabelle
- aus "Account_idAccount" wird eine "AccountID" , egal wo.
- und Feldbezeichner wie "text", "name", "datum" sind ganz, ganz äh-bäh, zumal wenn sie in 3 von 4 vorhandenen Tabellen auftauchen. Das provoziert Fehler und Missverständnisse.

Grüße
Biber
 
Zuletzt bearbeitet:
oke danke euch werde eure ratschläge beherzigen.

Ich habe aber noch zum Code ein par fragen.
SQL:
SELECT k.idKommentar, k.text, k.datum, acc.idAcconunt, acc.name
FROM Kommentar_has_Artikel kha
JOIN Kommentar k ON k.idKommentar = kha.Kommentar_idKommentar
JOIN Account acc ON acc.idAccount = k.Account_idAccount
JOIN Artikel art on art.idArtikel =kha.Artikel_idArtikel       <---------
WHERE Artikel.idArtikel = 1           <----------
ORDER BY k.datum ASC;

Wieso muss ich auch die Tabelle Artikel JOINen, wenn ich doch in der Tabelle Kommentar_has_Artikel
nach der idArtikel suche.

und wieso frage ich nach Artikel.idArtikel = 1 und nicht kha.idArtikel = 1.

Ich will ja alle Kommentare die zu dem Artikel ausgeben und die damit verbundenen Daten vom Kommentar.
Dafür muss ich doch nur in der Tabelle Kommentar_has_Artikel suchen.
 
Moin kuroo,

ich habe den JOIN auf die Artikel-Tabelle mit hineingenommen, weil du sonst keine Chance hättest, irgendwelche Infos aus der Artikeltabelle anzuzeigen.

Wenn du meinst, dir reichen die "Kommentar"-Felder und du auch nur die "Kommentierer" anzeigen willst, ohne mit anzuzeigen, welchen Artikel sie kommentiert haben, dann brauchst du den JOIN nicht.

Dann würde reichen:
SQL:
SELECT k.idKommentar, k.text, k.datum, acc.idAccount, acc.name as Kommentierer
FROM Kommentar_has_Artikel kha
JOIN Kommentar k ON k.idKommentar = kha.Kommentar_idKommentar
JOIN Account acc ON acc.idAccount = k.Account_idAccount
-- kann wech -- JOIN Artikel art ON art.idArtikel =kha.Artikel_idArtikel      
WHERE kha.Artikel_idArtikel = 1    -- statt art.idArtikel = 1        
ORDER BY k.datum ASC;

Da du in deinem Tabellenmodell sowohl von "Artikel" auf "Account" verweisen kannst (um den Artikel-Verfasser wiederzufinden) wie auch von den Kommentaren (um den Kommentar-Verfasser zu finden), habe ich in der Anzeige jetzt den Accountnamen umbenamst (" acc.name as Kommentierer").

Die Account-ID und die KommentarID sind aus meiner Sicht interne IDs, die im Resultset nicht benötigt werden, ausser eben für dich als Debug- und Kontrollhilfe.

Für den Otto-Normal-Anwender brauchen die nicht mit ausgegeben zu werden - der braucht nicht mal zu wissen, dass es dafür IDs gibt.

Grüße
Biber
 
- und Feldbezeichner wie "text", "name", "datum" sind ganz, ganz äh-bäh, zumal wenn sie in 3 von 4 vorhandenen Tabellen auftauchen. Das provoziert Fehler und Missverständnisse.

Mag ja sein, dass diese "äh-bäh" sind, aber ganz ehrlich, aus meiner Erfahrung heraus sind diese in der Praxis Gang und Gebe, zumindest "name". Bei über 100 Tabellen willst du einfach möglichst kurze Benennungen haben, dann hast du auch nicht mehr KommentarID oder Ähnliches, sondern nur noch ID. Natürlich müssen die Tabellen entsprechend gut benamst sein. Kommentar.ID ist letztendlich genauso gut wie Kommentar.KommentarID, meiner Meinung nach sogar fast besser da kürzer und nicht doppelt gemoppelt. In der Mapping Tabelle (hier Kommentar_has_Artikel <-- warum eigentlich Denglisch? ;-) ) muss die Eindeutigkeit natürlich beibehalten bleiben.

Die Wahl von schlicht ID lässt sich sogar noch tiefgründiger erläutern... Natürlich liegt auf der Datenbank fast immer eine Applikation, sei es nun z.B. eine Java (objektorientierte) Anwendung mit JPA und vielen Tabellen. Mit JPA werden sozusagen Objekte auf deine Datenbank-Entities gemappt. Und damit du nicht für jede Tabelle die ID und entsprechende Funktionen neu implementieren bzw. an x Stellen warten musst, lässt du alle Objekte einfach von dem ID-Objekt erben. Ich will damit nur sagen, eindeutige Namen sind nicht immer gut, vorallem wenn bestimmte Sachen verallgemeinert werden sollen. Je größer die Applikation desto größer ist der Drang nach Verallgemeinerung und damit auch nach Kürzung der Namen.

"datum" ist da schon wieder ein wenig spezieller, hier weiß man in der regel schlichtweg nicht was das Datum darstellen soll. Deswegen wird hier doch eher zu längeren Benennungen gegriffen, jedoch nicht etwa "KommentarDatum", sondern ich meine sowas wie "Aenderungsdatum", "Speicherdatum", "Eingabedatum", "Registierungsdatum", "Erstelldatum" etc.
 
Zuletzt bearbeitet:
Moin HonniCilest,

wie du schon richtig schreibst: durch die (in aller Regel) objektorientiert tickende Applikation werden Objekte auf Entities gemappt.

Und Gottseidank versteifen sich die wenigsten Java-Entwickler darauf, dass sich "eigentlich" alles sinnvoll von einem einzigen Pauschal-Objekt ableiten liesse.
Auch da wird letztlich schon in "Entitäten" gedacht - und so findet es sich auch in einem Datenbankmodell wieder.

Ja, auch ich kenne Modelle mit einem guten Dutzend Dimensionstabellen, die "eigentlich" alle nur aus 2 Feldern namens "ID" und "Bezeichnung" bestehen.
Ist ja alles gleich.... die ersten 3 Wochen.

Danach sind 5 der "Bezeichnung"-Felder Varchar(100), eins ist CHAR(50), eins ein CLOB und 7 Felder sind Varchar(4000). Ist das immer noch die gleiche Entität "Bezeichnung"?

Vielleicht, aber offensichtlicher wird es bei den IDs.
Eine KundenID ist nicht die gleiche Entität wie eine Auftrags-ID, eine RechnungsID, eine MitarbeiterID oder eine KostenstellenID. Jede dieser IDs taucht ja naturgemäß in x weiteren Child-und Zuordnungstabellen auf und in jeder, aber auch jeder käsigen Faktura-Appz hast du mindestens eine Tabelle dabei, wo 4 dieser 5 Ids vertreten sind.
Was hilft es denn dann, dass ich sie in der jeweiligen Stammdaten/Parenttabelle weitblickend "Id" benamst habe?

Es gab Zeiten und Programmierumfelder, in denen Feld- und Tabellennamen noch restriktiver reglementiert waren - lange Zeit ja max 8 Zeichen NUR IN GROSS.
Und bei einer in Deutschland sehr bekannten Firma ("Software aus Pakistan") sind sogar max 4 Zeichen nur IN GROSS in deren hierarchischem Knoten/Baumgeknösel üblich.

Vielleicht kommt mein Widerwille gegen "ID", "NAME", "TEXT" daher, dass ich mal früher so modellieren MUSSTE.
Ich bin jedenfalls mit "KundenID", "AuftragsID" , "ChildID" und "ParentID" glücklicher als mit einem Standard-Feld namens "ID" in jeder Tabelle.

Ist aber vollkommen subjektiv - das ermöglicht mir, zu meinem "äh-bäh" zu stehen. ;-).

Schönen Abend und Grüße
Biber
 
Zuletzt bearbeitet:
Zurück