mmofacts.com

Gebäudeinformationen mittels Join

gepostet vor 19 Jahre von friedenspanzer
Und wieder ich mit folgendem Problem: Ich kenn mich nicht mit Joins aus und weiß nicht wie ich den zum Arbeiten bring. Ich weiß nicht mal ob man ihn hier benutzen kann.

Situtation: Ich habe eine Tabelle in der steht wie viele Gebäude welcher Sorte auf welcher Insel gebaut wurden (Spalten: Insel, Geb, Anzahl). Die Gebäudeinformationen sind in einer anderen Tabelle gespeichert.

Ist es jetzt irgendwie möglich diese Informationen gleichzeitig auszulesen? Also dass für jedes Gebäude auf der Insel ein Array mit den Gebäudeinformationen ausgelesen wird oder so. Der einzige Join den ich zustande kriege schafft nur das erste Gebäude

In dem Bewusstsein dass ich wie schon so oft geholfen kriege Danke im Voraus :wink:
gepostet vor 19 Jahre von Sarge
ein select a.was , a.auch , b.immer from a left join b on a.gid = b.gid;

wo a deine gebäude tabelle und b deine inseltabelle ist tut es nicht einfach? oder überseh ich grad irgendwas
gepostet vor 19 Jahre von Derpendja
Du erhälst auf diese Weise eine Tabelle, die dir alle Daten liefert, aber du bekommst natürlich pro Gebäude und Insel einen Datensatz - d.h. nicht pro Insel einen Datensatz. Durch den LEFT JOIN erhälst du alle Inseln - auch die, die keinerlei Gebäude haben, dafür erntest du bei den Gebäudedaten dann ein NULL. Beim INNER JOIN würdest du nur Inseln mit Gebäudedaten erhalten, die auch Gebäude haben.

Insel-ID, Geb-ID, Anzahl, Geb-Daten_1, ...

also z.B.
1,1,1,'Haus'
1,2,2,'Kaserne'
1,3,3,'Tretmühle'
2,1,1,'Haus'
2,3,1,'Tretmühle'
etc. pp.

Wobei man jetzt natürlich darüber sinnieren könnte, ob man die Anzahl überhaupt mitschreibt oder per COUNT sich holt - solltest du verschiedene Ausbaustufen der Gebäude vorhalten, bleibt dir sowie so nicht viel übrig, als pro Gebäude auf einer Insel einen Datensatz fortzuschreiben, bzw. pro Ausbaustufe dir die Anzahl in der DB vorzuhalten.
gepostet vor 19 Jahre von Chojin
Die Zauberworte lauten: "JOIN LEFT" :roll:

a.bauwerkstyp = b.beschreibungsid

@Derpendja: welche Daten man erhällt hängt ganz davon ab, welches die Haupttabelle ist und welches die "Ge-JOIN-te" Tabelle ist.

reg4rds
chojin
gepostet vor 19 Jahre von The_Alien
Hm - als Anfänger von Joins könnte ich da nirgends was rauslesen.
Ich habe das über ein Buch (18 Euro und alles über tabellen was man wissen muß drinne) gelernt.

So sähe dann wohl ca. dein Join aus (nur ein bsp.):

SELECT insel.*,buildings.* FROM insel LEFT JOIN buildings ON buildings.id=insel.gebaudeid WHERE ....

Kannst natürlich noch eine Whereklausel etc einbringen und die * anpassen (am, besten nur das holen was man braucht und nicht immer alles)

Bei genauerer Angabe der Tabellen könnte man dier auch einen Join fertig machen - dann "erkennt" man das besser.
gepostet vor 19 Jahre von Derpendja
Ich gehe in der Regel davon aus, dass man von den Stammdaten auf die Bewegungsdaten verknüpft und halte das auch für die logischte Vorgehensweise in fast allen Fällen.

Bei JOINS empfiehlt es sich in meinen Augen, vermehrt Einschränkungen in die Verknüpfungsbedingungen einzubinden, statt in den WHERE-Teil, also z.B. für alle Gebäude einer Insel

SELECT insel.id,buildings.id, [...] FROM insel LEFT JOIN insel_has_buildings ON insel.gebaudeid = insel_has_buildings.gebauedeid AND insel.id = 1

Bücher sind zum Einstieg ganz brauchbar, Erfahrung erschlägt aber bei Datenbankabfragen mehr als Theorie - also üben, üben, üben :wink:

Wobei man sich über Datenbankendesign ja vortrefflich streiten kann...
gepostet vor 19 Jahre von friedenspanzer
Original von The_Alien
Hm - als Anfänger von Joins könnte ich da nirgends was rauslesen.


Stimmt wohl :wink:

Original von The_Alien

SELECT insel.*,buildings.* FROM insel LEFT JOIN buildings ON buildings.id=insel.gebaudeid WHERE ....

Danke, werd das nachher ausprobieren.

Den anderen natürlich auch Danke, auch wenn ich kein Wort verstanden hab ^^

[EDIT]
Eben ausprobiert. Es zeigt immer noch nur die Daten des Gebäudes mit der niedrigsten ID an

JETZT mal mit genaueren Daten über die Tabellen. In der Tabelle "gebs" stehen Informationen über die Gebäude (ID, Name, Beschreibung...). Die Tabelle "gebs_gebaut" enthält die Spalten "Insel", "Geb" und "Anzahl". Natürlich ist Insel die ID der Insel, Geb die ID des Gebäudes und Anzahl... die Anzahl ^^.

Als Query hab ich das hier benutzt:
SELECT gebaut.*, gebs.* FROM gebs_gebaut AS gebaut LEFT JOIN gebs ON gebs.id = gebaut.geb WHERE gebaut.insel = '" . $this->_id . "'
´

Wo GENAU ist jetzt der Fehler?
gepostet vor 19 Jahre von knalli
Sofern es sich um eine komplett gültige Relation handelt, wäre - analog zum obrigen Query - folgende Variante wesentlich besser. Im Ergebnis - sofern gültig relativ - das Gleiche, aber wesentlich schneller, also effizienter.

 

SELECT gebaut.*, gebs.* FROM gebs_gebaut AS gebaut LEFT JOIN gebs ON gebs.id = gebaut.geb WHERE gebaut.insel = '" . $this->_id . "'


=>

 

SELECT gebaut.*, gebs.* FROM gebs_gebaut AS gebaut, gebs WHERE gebs.id = gebaut.geb AND gebaut.insel = '" . $this->_id . "'


Da dies ein Beispiel ist, denke ich, dass das '*' noch entfernt wird, weil dies die Effektivität senkt.
gepostet vor 19 Jahre von Derpendja
SELECT gebaut.*, gebs.* FROM gebs_gebaut AS gebaut LEFT JOIN gebs ON gebs.id = gebaut.geb WHERE gebaut.insel = '" . $this->_id . "'


Mal ganz davon abgesehen, dass gebaut.insel numerisch ist und daher es wohl eher

WHERE gebaut.insel = ' . $this->_id;

heißen müsste, sehe ich jetzt nicht, warum die DB nur ein Ergebnis liefert. Gut, man kann natürlich von der Stammdatentabelle (gebs) aus auf die Bewegungsdatentabelle (gebs_gebaut) verknüpfen und nicht anders herum, aber auch das sollte keinen Unterschied machen.

Ein LIMIT 1 bei MySQL oder TOP 1 beim SQL-Server hast du nicht noch irgendwo?
Passen die Daten in den Tabellen? Gibt es dort auch mehrere geb-IDs in der gebs_gebaut, die es auch in der geb gibt (nicht lachen, manche Probleme sind so trivial, dass man den Baum vor lauter Bäumen nicht sieht).
Bekommst du ein anderes Ergebnis, wenn du der Datenbank direkt in einem DB-Verwaltungsprogramm (z.b. phpmyadmin) befragst, statt aus der Source?
gepostet vor 19 Jahre von The_Alien
SELECT gebaut.*, gebs.* FROM gebs_gebaut AS gebaut LEFT JOIN gebs ON gebs.id = gebaut.geb WHERE gebaut.insel = '" . $this->_id . "'


Da ja eigentlich alle Gebäude an sich existieren müßen (da sie ja gebaud wurden) braucht man hier nichtmal unbedingt einJoin - da Left Joins den Hauptvorteil haben Das nicht alle Daten vorhanden sein müßen.

Da aber alles was mal gebaut wurde ja auch unter Gebäude steht kann man das auch in der Where klausel machen:

SELECT gebs_gebaut.*, gebs.* FROM gebs_gebaut,gebs  WHERE gebs.id=gebs_gebaut.geb AND gebs_gebaut.insel = '". $this->_id ."'


Als Join würde ich das so schreiben:
SELECT gebs_gebaut.*, gebs.* FROM gebs_gebaut LEFT JOIN gebs ON gebs.id=gebs_gebaut.geb WHERE gebs_gebaut.insel = '". $this->_id ."'


Eben ausprobiert. Es zeigt immer noch nur die Daten des Gebäudes mit der niedrigsten ID an

Ich denke mal damit meinst du das zwar die Inseldaten stimmen aber der alles nur mit dem Gebäude der ersten ID aus `gebs`verknüpft.

Wie schon von Derpendja erwähnt würde ich das Query mal in einm Verwaltungsprogram wie phpmyadmin oder ähnlichem "testen" - da probier ich meine querys auch erstmal aus sobald es komplizierter wird.
gepostet vor 19 Jahre von knalli
Etwas anderes habe ich aber auch nicht gemeint :wink:
gepostet vor 19 Jahre von The_Alien
Gehts denn nun? Wenn nicht kann man sich ja mal IRC oder TS zusammensetzen. Denn Joins sind (meiner Erfahrung nach) das wichtigste was es gibt was die Performance angeht (im gegensatz zum einzelabruf in Schleifen etc).
gepostet vor 19 Jahre von TheUndeadable
Leider habe ich deine Frage nicht verstanden, sonst könnte ich dir helfen ;-)


Wie schon von Derpendja erwähnt würde ich das Query mal in einm Verwaltungsprogram wie phpmyadmin oder ähnlichem "testen" - da probier ich meine querys auch erstmal aus sobald es komplizierter wird.

Ich persönlich nutze hin und wieder den Query-Editor von MS Access. Evtl besitzt du ja eine 'Kopie'.
gepostet vor 19 Jahre von friedenspanzer
Stimmt, in einen externen Programm wurde ein korrektes Ergebnis angezeigt. Ich hab das ganze jetzt anders gelöst und sogar einen Query gespart

Auf diese Diskussion antworten