[SQL] JOIN verständnis ** erledigt **

strolch00

redraft.de
ID: 155297
L
21 April 2006
1.684
72
Hi @all,

ich bin nun seit geraumer Zeit an einer Datenbank abfrage dran aber immer geht irgendwas nicht so wie es sein muss.

Folgende Dinge sind gegeben:
tab_a
user_id | item_x | level

tab_b
item_x | level | item_y | score

tab_c
item_x | level | item_y | score

tab_d
item_y | item_label

Was ich herausfinden will ist folgendes:
tab_b ist der die Verbrauchstabelle und tab_c ist die Gutschrifttabelle

Ich brauche jetzt alle item_label und die summe von score aus tab_b und summe von score aus tab_c welche zu meiner user_id in tab_a existeren, trotzdem nachher noch alle restlichen item_label.

Ich bekomme es mit JOIN zwar hin aber die abfrage dauert zu lang und ist uneffizient.

Wie muss ich das am effektivsten angehen? Mit meinen möglichkeiten addiert der einfach alles zusammen und bringt mir falsche Werte bei verbrauch und gutschrift oder liefert mir die richtigen aber nicht alle restlichen item_label.
Ich bin über jeden Tipp dankbar.

Danke schonmal.
 
Zuletzt bearbeitet:
PHP:
"SELECT d.`item_label` AS `label`
		, IF(SUM(b.`score`) > 0, SUM(b.`score`), 0) AS `produktion`
		, IF(SUM(c.`score`) > 0, SUM(c.`score`), 0) AS `verbrauch`
	FROM `tab_a` AS `a`
	JOIN `tab_b` AS `b`
		ON (b.`item_x` = a.`item_x`
			AND b.`level` = a.`level`)
	JOIN `tab_c` AS `c`
		ON (c.`item_x` = a.`item_x`
			AND c.`level` = a.`level`)
	CROSS JOIN `tab_d` AS `d`
		/*ON(d.`item_x` = b.`item_x`
			OR d.`item_x` = c.`item_x`
			OR b.`item_x` IS NULL
			OR c.`item_x` IS NULL)*/
	WHERE a.`user_id` = 4
	GROUP BY (d.`item_label`)
	ORDER BY d.`item_x`"

Ich hoffe das ich den jetzt richtig umgebaut habe mit den Tabellennamen und Spaltenbezeichnungen, aber es schaut so ok aus.
 
Zuletzt bearbeitet:
Grade die Tabellennamen sind das interessante an der Sache. Um Queries zu schreiben muss man verstehen mit was man es zu tun hat und was man will... ohne dieses wissen kommt nur quatsch raus. Ich weiß zwar noch dass es um Rohstofe geht und um den verbrauch von Gebäuden... aber die Stuktur ist mir unklar. Es scheint so als würdest du immer noch versuchen den lokalisierten Name des Rohstofes auszulesen, dass ist aber mit der Sturktur nicht effizient möglich mit Mysql. Entweder du änderst die Sturktur der Datenbank oder du leist die Namen einfach schon vorher aus und arbeitest dann mit den indizien.
 
Ok Zero ich bau es nochmal so um wie es funktioniert hat, wo es nur die schlechte Indizierung hatte. Den query kann ich ja später wieder entfernen.

Aber mal noch einen Frage, wie würdest Du denn die Strucktur wählen???

Zur info es gibt 5 Völker ca 19 Rohstoffe wobei nicht jedes Volk die gleichen Rohstoffe hat.

Ich habe es jetzt so das in einer Tabelle die Rohstoffe stehen mit nation_id
in einer anderen Tabelle stehen die Gebäudeproduktion und in einer dritten der Gebäudeverbrauch. Und mit der vierten Tabelle verbinde ich das ganze in dem dort gespeichert sind village_id, building_id, level.

Mir kommt langsam der Gedanke ich habe es zu sehr aufgesplittet.

*edit
So Zero hier ist mein Query:
*** entferntt ***

Hier noch das dazugehörige EXPLAIN:


Soweit funzt des ganz super, bis auf die Performance frage. Hier mal nen Teil der Ausgabe:
...
[3] => Array
(
[label] => Getreide
[produktion] => 5.00
[verbrauch] => 0.80
)

[4] => Array
(
[label] => Kohle
[produktion] => 0.00
[verbrauch] => 0.00
)

[5] => Array
...

Hey Zero habe es hinbekommen mit einem Subselect:
*** entferntt ***

der läuft wenigstens in der hälfte der Zeit des oberen kompletten JOIN Query´s. Hier gleich das EXPLAIN dazu:


Kann man an dem noch etwas verbessern??? In dem man evtl die Indizie´s ändert oder so?
 
Zuletzt bearbeitet: