Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#1

SQL Vereinfachen

  Alt 16. Feb 2012, 15:06
Datenbank: MySQL • Version: 4.1.9 • Zugriff über: UnIDAC
Spätmahlzeit.

Ich habe folgendes Szenario:
In meiner DB habe ich eine Produktionsanlage abgebildet, von der der hier wesentliche Teil eine Menge von Behältern ist. Diese Behälter können Quellen und/oder Ziele für andere Behälter sein, was durch die Verrohrung vorbestimmt ist. Einige Behälter beinhalten Rohstoffe.
Der Anlagenbediener kann sich aus diesen Rohstoffen ein Rezept nach Belieben anfertigen, und der Anlage dann zur vollautomatischen Produktion vorgeben. Ich möchte bei der Vorgabe eines Rezeptes einen Auswahldialog haben, der mir anzeigt, welche Zielbehälter von allen Quellbehältern erreicht werden können, die die dort angegebenen Rohstoffe beinhalten.

Tabellen (nur die relevanten Felder):
beh (Behälterdaten)
- id (autoinc)
- Behälternummer
- Behältername
- Rohstoff (im Behälter)

qundz (Quellen und Ziele - Kreuztabelle der Behälternummern aus "beh" untereinander, gibt an wer wen wie direkt erreichen kann)
- id (autoinc)
- Quelle
- Ziel

rezpos (Rezeptpositionen aller Rezepte. Die mit typ=1 sind Dosier-Angaben (es gibt noch andere, die hier aber keine Rolle spielen sollen))
- id (autoinc)
- Rezeptnummer
- Typ
- Rohstoff

Es gibt also z.B. ein Rezept, in das soll Wasser, Wein und Orangensaft. Ich möchte nun alle Zielbehälter ermitteln, die Quellbehälter direkt angeschlossen haben, in denen alle 3 Rohstoffe vorhanden sind. Sprich die Behälter, in denen das Rezept angefertigt werden kann. Behälternummer und Behältername.

Im Moment mache ich das so:
Code:
SELECT k.ziel, e.name FROM
  (SELECT COUNT(z.id) qcount, z.ziel FROM                                                                // Zähle die erfüllbaren Dosierpositionen für alle Ziele, die von den beteiligten Quellbehältern erreicht werden können
    (SELECT p.id, q.ziel FROM beh b
     JOIN (SELECT id, rohstoff FROM rezpos WHERE rezeptnummer=:rn AND typ=1) p ON b.rohstoff = p.rohstoff // aus dem gewünschten Rezept "rezeptnummer"
     JOIN qundz q ON b.behaelternummer = q.quelle) z
   GROUP BY z.ziel) k
JOIN (SELECT COUNT(id) mcount FROM rezpos WHERE rezeptnummer=:rn AND typ=1) m                            // Zähle alle Dosierpositionen im Rezept
JOIN beh e ON k.ziel=e.behaelternummer                                                                   // Zielbehälternamen anflanschen
WHERE mcount=qcount                                                                                      // Nur die anzeigen, wo "möchliche Anzahl zu bedienender Positionen" der "gewünschten Anzahl zu bedienender Positionen" entspricht
Das tut was es soll, ist aber ein Monster (und ein wenig von hinten durch die Brust irgendwie). Da meine Hirnverknotung aber gerade recht hoch ist, komme ich nicht ganz auf den einfachen Weg, den es vermutlich dafür gibt. Mag mir da wer auf die Sprünge helfen?
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat