Select Abfrage für MySQL Datenbank m. Abzweigungen

Hallo,

ich bastle gerade an einer Datenbank und es tauchen ständig neue Fragen auf, die mir leider keine Ruhe lassen. In meiner Datenbank möchte ich beispielhaft verschiedene Peripheriegeräte speichern. Jeder Peripheriegerättyp besitzt unterschiedliche Eigenschaften und erhält daher eine eigene Tabelle:

produkt
+------------+--------------+-------------+--------------+
| produkt\_id | hersteller | produktname | type\_codiert |
+------------+--------------+-------------+--------------+
| 1 | Macrosoft | Speedprint | 1 |
| 2 | Techsoft | Hi-Scan | 3 |
| 3 | Geraetomatic | Cutomatic | 2 |
| 4 | Macrosoft | Printbox | 1 |
+------------+--------------+-------------+--------------+

typ
+-------------+----------+
| typ\_codiert | typ\_name |
+-------------+----------+
| 1 | Drucker |
| 2 | Plotter |
| 3 | Scanner |
+-------------+----------+

drucker
+------------+--------------------+---------------+--------------------+
| produkt\_id | druckertyp\_codiert | seiten\_minute | beidseitig\_codiert |
+------------+--------------------+---------------+--------------------+
| 1 | 1\* | 15 | 1 |
| 4 | 2 | 12 | 2 |
+------------+--------------------+---------------+--------------------+
\* Anmerkung: z.B. "1" für "Laser" und "2" für "Tintenstrahl"

plotter
+------------+------------------+
| produkt\_id | max\_schnitttiefe |
+------------+------------------+
| 3 | 0.8 |
+------------+------------------+

scanner
+------------+----------------+--------------------+
| produkt\_id | max\_aufloesung | durchlicht\_codiert |
+------------+----------------+--------------------+
| 2 | 1200 | 1\* |
+------------+----------------+--------------------+
\* Anmerkung: z.B. "1" für "Ja" und "2" für "Nein"

Jetzt habe ich etwa ein Suchformular, welches eine Suche nach dem Hersteller und/oder dem Produktnamen erlaubt. Suche ich etwa nach „Techsoft“ sollte die Ausagabe wie folgt aussehen:

Hersteller: Techsoft
Produktname: Hi-Scan
Typ: Scanner
Maximale Auflösung: 1200dpi
Durchlichteinheit: Ja

Gut, die Ausgabe lässt sich in PHP mit einer Switch Anweisung für die Fälle „Drucker“, „Plotter“ und „Scanner“ gestalten. Aber wie kann bzw. soll die SELECT Abfrage aussehen?

Schöne Grüße, Q_5

Entscheidungen in Abfragen
Moin, Q_5,

soweit ich weiß, gibt es keine Möglichkeit, Entscheidungen so in eine Query einzubauen, dass je nach Zwischenergebnissen mal diese, mal jene Daten zurückgeliefert werden. Anders gesagt: Aus welche Quellen die Daten bezogen werden sollen, muss beim Entwurf der Query bereits bekannt sein.

Gruß Ralf

Hallo Ralf,

danke für deinen Post, auch wenn ich über diese Antwort nicht erfreut bin. Ich habe also mein Suchformular mit zwei Textfeldern für „Hersteller“ und „Produktname“ sowie die oben aufgeführte Datenbank. Was mir allderings fehlt ist eine Lösung des Problems. Hast du - oder auch jemand anderer - einen konkreten Vorschlag? Probleme dieser Art sollten doch öfter auftreten, möchte man meinen.

Moin, Q_5,

keine Lösung, nur ein Ansatz: Reports lassen sich aus Subreports zusammenstellen, die haben je ihre eigenen Quellen und können so aufgebaut werden, dass sie im speziellen Fall leer bleiben - so wie beim Drucker, der gewiss keine Durchlichteinheit hat.

Mir sind auch schon „Report-Generatoren“ vom Typ eierlegende Wollmilchsau begegnet, immer mit dem Anspuch, der Benutzer müsse nur noch ankreuzen, was er braucht. Die führen dann regelmäßig zu derart unsittlichen Anforderungen, und der Betreuer vor Ort darf dann die Melange ausbaden, die sich aus Heilsversprechen einerseite und Unverstand andererseits ergibt.

Gruß Ralf

Hallo Ralf,

leider verstehe ich nicht was mit Reports bzw. Subreports gemeint ist. Mit MySQL bzw. PHP beschäftige ich mich erst seit wenigen Wochen, daher bin ich wohl noch mehr als grün hinter den Ohren. Ich bin allerdings fleißig am tüfteln und bin auf folgende Abfrage gekommen:

select produkt.*,
typ.typ_name,
drucker.druckertyp_codiert, drucker.seiten_minute, drucker.beidseitig_codiert,
plotter.max_schnitttiefe,
scanner.max_aufloesung, scanner.durchlicht_codiert
from produkt
join typ
on produkt.typ_codiert = typ.typ_codiert
left join drucker
on produkt.produkt_id = drucker.produkt_id
left join plotter
on produkt.produkt_id = plotter.produkt_id
left join scanner
on produkt.produkt_Id = scanner.produkt_id
where produkt.hersteller like ‚%macro%‘;

Ergebnis:

<small>+------------+------------+-------------+-------------+----------+--------------------+---------------+--------------------+------------------+----------------+--------------------+<br>| produkt_id | hersteller | produktname | typ_codiert | typ_name | druckertyp_codiert | seiten_minute | beidseitig_codiert | max_schnitttiefe | max_aufloesung | durchlicht_codiert |<br>+------------+------------+-------------+-------------+----------+--------------------+---------------+--------------------+------------------+----------------+--------------------+<br>| 1 | Macrosoft | Speedprint | 1 | Drucker | 1 | 15 | 1 | NULL | NULL | NULL |<br>| 4 | Macrosoft | Printbox | 1 | Drucker | 2 | 12 | 2 | NULL | NULL | NULL |<br>+------------+------------+-------------+-------------+----------+--------------------+---------------+--------------------+------------------+----------------+--------------------+<br></small>

Hältst du diesen Lösungsweg für „gut“? Als Anfänger gibt es ja u.U. Dinge, die man nicht bedenkt. Grundsätzlich erhalte ich mit dieser Abfrage alle Daten, die ich benötige. Das ist ein großer Schritt für mich, ich hoffe in die richtige Richtung.

Hi Q_5,

leider verstehe ich nicht was mit Reports bzw. Subreports
gemeint ist.

pardon, mir scheint, ich bin heute neben der Spur - die gibt es nur im ACCESS (und ähnlichen DBMS).

Hältst du diesen Lösungsweg für „gut“?

ich bin da wenig kompetent; der Auftraggeber sagt, was er gut findet oder eben nicht :smile: Und mir als Auftraggeber stellte ich sofort die Frage, ob ein Drucker überhaupt eine Eigenschaft „durchlicht_codiert“ besitzt - wenn nicht, würde ich sie auch nicht als „NULL“ sehen wollen.

Möglicherweise habe ich die Anforderung nicht verstanden, ich habe das so interpretiert, dass ergänzende Daten je nach Bedarf angezeigt werden sollen, so zB beim Drucker die Anzahl Seiten pro Minute, beim Scanner nicht.

Gruß Ralf

Möglicherweise habe ich die Anforderung nicht verstanden, ich
habe das so interpretiert, dass ergänzende Daten je nach
Bedarf angezeigt werden sollen, so zB beim Drucker die Anzahl
Seiten pro Minute, beim Scanner nicht.

Doch das stimmt schon, was angezeigt werden soll bestimmt dann mein PHP Skript. Mein Problem war, die entsprechenden Daten erstmal aus der Datenbank zu bekommen. Eventuell drücke ich mich auch missverständlich aus :wink:

Also ich muss mal eingreifen …
Wenn den der Query so schwer wird, das das Ergbniss zuviele redundancwerte erzeugt (also deine switch version) . Dann ist es einfacher teile der Daten einzulesen und diese dann mit der Programmiersprache zu Verbinden.

als Beispiel

ProduktID ProduktName

Beziehung_ProduktID Beziehung_TeileID

TeileID TeileName

Kann man auch so mit z.b. php bearbeiten.

Ein Beispiel :

SELECT ProduktID , ProduktName
FROM Produkte

while ($row = readrowsql) {
$produkt[$row[‚ProduktID‘]]=array( „name“ => $row[‚ProduktName‘],
„Teile“ => array());
}

SELECT Beziehungen.Beziehung_ProduktID as PID,
Teile.TeileID as TID,
Teile.TeileName as TName
FROM Beziehungen
JOIN Teile
ON Beziehungen.Beziehung_TeileID = Teile.TeileID

while ($row = readrowsql) {
$produkt[$row[‚PID‘]][„Teile“][]=array( „ID“ => $row[‚TID‘],
„name“ => $row[‚TName‘]);
}
var_dump($produkt);

Ich habe schon daran gedacht, in einer ersten Abfrage nur die Tabelle „Produkt“ auszulesen und je nach Gerätetyp weitere Abfragen durchzuführen. Allerdings plane ich für später ein erweitertes Suchformular mit Formularelementen für die meisten Geräteeigenschaften (z.B.: Liste alle Drucker der Marke XY, deren Maximalauflösung min. 800dpi beträgt.). Diese Abfragen scheinen mit „meiner“ Methode nach ersten Tests zu funktionieren. Mit mehreren Abfragen ist das wohl nicht möglich, zumindest habe ich keine Lösung gefunden. „Null“ Werte nur in der Abfrage - nicht aber in der Datenbank selbst - sind wohl nicht so schlimm, das hoffe ich zumindest. Ich bin natürlich bemüht meinen Code so einfach wie möglich zu halten, aber ein wenig Komplexität lässt sich wohl nicht vermeiden.

Frohe Ostern!

Hmm ich find dein Ansatz Richtig . Die Beziehungen mit Extra Tabellen .
Wenn du noch ein bisschen mehr von JOINS ON und WHERE HAVING benutzt, sollten doch komfortable Ergebnise erzielt werden. Wenn man das dann in ein Objekt packt und dann das Objekt bedarfsgerecht verarbeitet und ausgibt, dann sollte das doch Wunderbar funktionieren.

  1. Eingabe : SQL Abfrageergebnis in DatenObjekte strukturiert einlesen
  2. Verarbeitung : DatenObjekte verarbeiten , update
  3. Ausgabe : DatenObjekte ausgeben HTML

Wie weit man eine Datenbank einer Normalisierung unterzieht ist eine andere Geschichte .

Wenn du noch ein bisschen mehr von JOINS ON und WHERE HAVING…

„Having“ kannte ich bisher nicht. Leider weiß ich deshalb auch nicht so recht, welche „Ausgabe-Tabelle“ dir vorschwebt.

Wie weit man eine Datenbank einer Normalisierung unterzieht
ist eine andere Geschichte .

Redunanzen gibt es anscheinend in der Spalte Hersteller, allerdings erscheint mir die Codierung der Spalte auch nicht optimal (besonders bei vielen und immer wieder neuen Herstellern).