Mysql group

Hallo,

bei solchen Abfragen bietet sich immer das „JOIN“ an, da es leider immer wieder mal sein kann, dass z.B. nicht alle Hersteller in der Hersteller-Tabelle vorhanden sind. Mit einer WHERE-Verknüpung würde dann die gesamte Stereoanlage rausfallen – hingegen mit JOIN hast du schlimmstenfalls ein leeres Herstellerfeld (NULL genannt).

Ich habe hier ein gutes Beispiel gefunden, was deinem Problem ähnlich ist. Leider ein fremdes Forum, aber das Internet lebt von Verlinkung. Also hier:

http://www.tutorials.de/forum/relationale-datenbanks…

LG

Ajo

Hi Oliver,

außer dem herstellername-problem enthält dein code noch einen Fehler:
where stereoanlage.id=1
… kann nicht gehen, deine Komponenten-Tabellen enthalten keine stereoanlage_id, und die Tabelle stereoanlage kommt im select gar nicht vor - das wird vom mysql bereits mit ‚Unknown column‘ abgelehnt.

Du brauchst ein ziemlich kompliziertes und langes Statement, da empfehlen sich Aliasnamen für die Tabellen.
Weiterhin benötigt jede Komponente ihren eigenen Herstellernamen, der über [komponente].hersteller_id = hersteller.id gefunden wird. Da das Feld in hersteller immer firmenname heisst, muss es bei Mehrfachverwendung in einem select ebenfalls mit unterschiedlichen Aliassen versehen werden. Und schließlich muss die Tabelle hersteller mit jeder komponente separat verknüpft werden, damit sind Tabellen-Aliasse sowieso zwingend.
Bei der alias-Syntax ist noch zu beachten, dass die Tabellen-Aliasse im FROM definiert werden, aber im SELECT bereits verwendet werden können.

Also…
SELECT
– evtl. irgendwas „eigenes“ aus stereoanagen
S.name, S.preis,
– Komponenten und zugehöriger Hersteller
V.*, H_V.firmenname AS verst_hersteller,
B.*, H_B.firmenname AS boxen_hersteller,
D.*, H_D.firmenname AS dvdpl_hersteller
FROM
stereoanagen AS S,
verstaerker AS V,
hersteller AS H_V,
boxen AS B,
hersteller AS H_B,
dvdplayer AS D,
hersteller AS H_D
WHERE
V.id = S.verstaerker_id
AND
H_V.id = V.hersteller_id
AND
B.id = S.boxen_id
AND
H_B.id = B.hersteller_id
AND
D.id = S.dvdplayer_id
AND
H_D.id = D.hersteller_id
AND
– evtl. eine bestimmte anlage, sonst alle
S.id = 1

lass mal hören, ob’s tut …

Gruß
Thomas

Hallo, Oliver,

fuer deine Anfrage musst du die Hersteller-Tabelle mit jeder der Komponenten-Tabellen erneut verknuepfen - du kannst den Feldern in der Abfrage dann neue Namen geben, um die Felder auseinander halten zu koennen.

Die Abfrage ist ziemlich lang formuliert, wird aber nicht allzulange laufen:

SELECT s.\*, dvdplayer.\*, verstaerker.\*, boxen.\*, h1.firmenname AS boxen\_firmenname, h2.firmenname AS verstaerker\_firmenname, h3.firmenname AS dvdplayer\_firmenname  
FROM stereoanlage AS s   
LEFT JOIN boxen ON s.boxen\_id = boxen.boxen\_id  
LEFT JOIN hersteller AS h1 ON h1.hersteller\_id = boxen.hersteller\_id  
LEFT JOIN verstaerker ON s.verstaerker\_id = verstaerker.verstaerker\_id  
LEFT JOIN hersteller AS h2 ON h2.hersteller\_id = verstaerker.hersteller\_id  
LEFT JOIN dvdplayer ON s.dvdplayer\_id = dvdplayer.dvdplayer\_id  
LEFT JOIN hersteller AS h3 ON h3.hersteller\_id = dvdplayer.hersteller\_id  
  
WHERE s.anlagen\_id = ?  

Du solltest aber beim Select keine wildcards(*) verwenden sondern explizit nur die Felder abfragen die du auch auswerten willst.

Eine Option zur Verringerung der Komplexitaet der Abfrage waere es, die Komponenten-Tabellen in einer Sicht(View) vorab mit ihrem Hersteller zu verknuepfen und dann nur noch die Views mit der Stereoanlage zu verknuepfen.

[http://dev.mysql.com/doc/refman/5.0/en/create-view.html]

Mit freundlichem Gruss,
Kai

Danke für die schnellen Antworten! Probiere es. Nun mit frischen und freiem Kopf. Gestern Abend ging nichts mehr.

Hi Ajo,

danke für Deine Ausführungen! Das ein Hersteller nicht drinnesteht? Hm, könnte im Fehlerfalle sein. Ansonsteb vermeide ich sowas immer duch select-Felder im Eingabe-Formluar oder ggfs. durch ein Autocomplete, welches aber keine eigenen Eingaben zulässt, sondern nur die Datenbankeingaben. Das einige wäre, wenn zB irgendjemand den hersteller löscht, der der zB wie Akai seinerzeit pleite geht.

Hi Ajo,

danke für Deine Ausführungen! Das ein Hersteller nicht drinnesteht? Hm, könnte im Fehlerfalle sein. Ansonsteb vermeide ich sowas immer duch select-Felder im Eingabe-Formluar oder ggfs. durch ein Autocomplete, welches aber keine eigenen Eingaben zulässt, sondern nur die Datenbankeingaben. Das einige wäre, wenn zB irgendjemand den hersteller löscht, der der zB wie Akai seinerzeit pleite geht…

Hi Thomas,

danke für Deine Ausführlichen Ausführungen! So in etwa hatte ich mir das auch vorgestellt. Allerdings hatte mir ein User einen Haken der Alias-variante aufgegeben.

Und zwar wenn zB der Hersteller Akai Pleite geht und daher gelöscht wird stimmen die Kriterien nicht mehr und die Stereoanlagenkombi geht flöten, wenn zufällig ein AKAI Verstärker dabei ist.Verdammt und die waren gut!

Hi kai,

danke das war die Lösung! Zum Verständnis für mich:
Im ersten part habe ich wie geabt die Felder angegeben, welche ich haben möchte.
Dann im from-Teil:
verknüpfe ich auch wie gehabt die hersteller_id aus der Komponenten Tabelle mit der id aus der Herstellertabelle, auch klar.

Der Knackpunkt ist jeweils die Zeile

  
LEFT JOIN hersteller AS h1 ON h1.hersteller\_id = boxen.hersteller\_id  
  

Dort spanne ich so zusagen drei „künstliche“ Spalten auf.
Also hinterlege ich unter h1 (erste künstliche Spalte) die Bedingungung/Beziehung zwischen DVD.hersteller_id und hersteller.id und unter h2 (zweite künstliche Spalte) die Bedingungung/Beziehung zwischen verstaerker.hersteller_id und hersteller.id und unter h3 (dritte künstliche Spalte) die Bedingungung/Beziehung zwischen boxen.hersteller_id und hersteller.id

Habe ich es verstanden oder ist da noch ein Denkfehler drin? Ein fettes Dankeschön für Deine Mühe!

Hi Thomas,
der Ansatz von Kai war der „etwas bessere“.

Denn ein Problem hätte die Lösung ohne join:
Sollte aus irgend einem Grunde mal der Hersteler gelöscht werden. (Pleite, Fehler, Praktikant),
schlägt die ganze Abfrage fehl.
So steht da nur in einer Spalte ein NULL.
Danke für Deine Mühe!
Oliver

Hi,

ja, einen JOIN wollte ich dir nicht zumuten :wink:
Allerdings löscht man in echten Datenbeständen auch keine Stammdaten, sondern versieht sie mit einem flag z.B. ‚deleted‘ - das kann man dann wieder prüfen bei Abfragen, bei denen dieser Status relevant ist. Du würdest dann eine Liste aller jemals definierten stereoanlagen bekommen, wenn du das kriterium nicht verwendest, und eine weitere der _lieferbaren_ anlagen unter Verwendung von „… AND hersteller.deleted = 0“. Vorteil: der Name des inzwischen nicht mehr existierenden Herstellers bleibt in jedem Fall verfügbar. Das ist bzgl. der Semantik der Daten korrekter, denn ein AKAI-Verstärker hat keinen Hersteller namens „NULL“ - sondern eben AKAI, auch wenn die inzwischen pleite sind.

Gruß
Thomas

Hallo Silke,

danke für Deine Mühe! Kai hatte mir letzten Endes den richtigen Ansatz gegeben.

Kompliziert, aber genial!

Gruß
Ollie

Hallo Silke,

danke für Deine Mühe! Kai hatte mir letzten Endes den
richtigen Ansatz gegeben.

Kompliziert, aber genial!

Fein :smile:

Hallo nochmal,

h1 - h3 sind keine Spalten, sondern Aliase, die dazu dienen die drei Tabellen, die ja alle „Hersteller“ heißen, zu unterscheiden, wenn du ihre Spalten verwendest. Ohne diese würde der Server bei jeder Verwendung einer Spalte von „Hersteller“ sagen „Die Spalte ist mehrfach vorhanden, ich weiß nicht was du von mir willst“ :wink: Also nennst du die erste Hersteller-Tabelle h1, die zweite h2 und die dritte h3 (Du kannst sie auch Hans, Gustav und Klaus nennen, ganz frei nach Belieben) und beim Auswählen einer Spalte sagst du dann halt h1.Name statt Hersteller.Name und damit ist es für den Server klar welche Herstellertabelle du willst.

Alle Klarheiten beseitigt? :wink:

Ciao!
Kai

Hai Kai,
jep, ich glaube ich habe es gecheckt.

Tatsächlich hatte ich schon mehrfach über join gelesen. Aber in 90% der Seiten steht exakt der selbe Text drin.

Wie schön join ist und wie toll und was man damit alles machen kann und warum, aber nicht wie.

Genau sowas wie hier habe ich gebraucht. Eine kleine Aufgabe, eine Lösung und eine Erläuterung. Damit kann ich dann experimentieren! Learning bei doing. Danke schön!
Aber ich denke, dass ich richtig liege, dass es schon etwas fortgeschrittener ist, was ich machen wollte.
:wink:
Aber Wahnsinn, der hatte der Serve doch mal eben etwas mehr als einige Milli-Sekunden zu rechnen.

Hallo Oliver Eikel,

es gibt natürlich auch in mySQL solche Abfragen wie group innerjoin und outerjoin. Ich selber habe bisher damit kaum gearbeitet. Deine Tabellen haben eine gemeinsame Beziehung: Hersteller. Es könnte sich daher eine Sortierung nach Herstellern anbieten:
Fa. XYZ bietet an DVD-Player, Verstärker usw.

Ich selber würde eher dazu neigen die Tabellen einzeln zu bearbeiten, und jeweils dazu die Hersteller zu suchen. Scheint mir im ersten Moment einfacher zu sein.
Eine bessere Lösung kann ich Dir so schnell nicht anbieten.

Viele Grüße
Werner

Moin Oliver,

so pauschal kann ich Dir das nicht beantworten, es gibt mehrere Wege, eine Datenbank, wie Du sie Dir in meinen Augen vorstellst, aufzubauen, und alle würden der 3. Normalform entsprechen.

Schick’ mir doch mal einen Dump der ersten 5 unterschiedlichen Datensätze, aus denen ich vernünftige Ergebnisse zaubern könnte.

Ohne eine Vorstellung zu haben WIE Diene Daten aufgebaut sind, kannst Du auch einen Arzt anrufen, ind Telefon husten und einen „gelben Schein“ erwarten.

Baer

Hallo Baer,

danke für Deine Mühe, ich habe es mittlerweile via join gelernt und gelöst! :smile:

Das machtgenau das was ich wollte nämlich 2 Ergebnisse aus einer Tabelle mit 2 Bedingungen in einer sql-Abfrage!
Gruß
Oliver