Mysql - Php Frage zur Syntax
kermit2004
- datenbank
- php
2 dedlfix
Hallo, nach langen Jahren wollte ich mir mal wieder eine Datenbank Anwendung schreiben und musste merken, dass meine MySql und PhP sehr stark gerostet sind - ich hoffe auf eure Hilfe.
Habe eine Datenbank mit drei Tabellen
Tabelle 1 Projekte mit Namen des Projekts und Start und End Datum:
p_id, p_name, p_start, p_ende,...
Tabelle 2 Material, Name Material und Gesamtanzahl des jeweiligen Material :
m_id, m_name, m_gesamtanzahl
Tabelle 3 Verknüpfung von Projekt mit Material und jeweilige Anzahl des im Projekt benötigten Materials:
mp_id, p_id, m_id, mp_anzahl
Ich möchte mir nun für einen bestimmten Zeitraum die gesamte Materialliste anzeigen lassen mit der Anzahl der in diesem Zeitraum verfügbaren Anzahl des jeweiligen Materials.
Und hier hakt es bei mir.
Ich kann mir die gesamte Materialliste anzeigen lassen, ich kann mir die Summen der jeweiligen im Einsatz befindlichen Materialien anzeigen lassen aber eine vernünftige Abfrage die mir anzeigt Material 1 nicht im Einsatz daher Anzahl m_gesamtanzahl, Material 2 im Einsatz daher Anzahl (m_gesamtanzahl-mp_anzahl), ... bekomme ich irgendwie nicht hin.
Habe mir beholfen, indem ich erstmal das gesamte Material abfrage und dann während der Ausgabe für jede Material_ID eine extra Abfrage mache ob das Material in diesem Zeitraum im Einsatz ist. Das funktioniert zwar, ist Performance technisch auch nicht so das Problem (die Materialliste ist relativ klein) aber schön ist was anderes....
Wie würde eine MySql-Abfrage aussehen, die auf einmal die beiden Abfragen verbindet?
Gibt es eine andere Lösung? Hatte mir z.B. gedacht, dass ich erst das ganze Material abfrage, das in diesem Zeitraum im Einsatz ist, das in ein Array speichere und dann eine zweite Abfrage nach dem gesamten Material - allerdings komme ich hier mit meinen PHP Kenntnissen an ein Limit, da ich noch nicht wieder rausgefunden habe wie ich die Arrays vergleiche, bzw. wie ich rausfinde ob m_id in beiden Arrays vorhanden ist....
Hoffe ich habe mich einigermaßen verständlich ausgedrückt und ihr könnt mir helfen. Achja, in der Test Umgebung habe ich MySql 5.0.67 - weiß allerdings noch nicht welche Version ich in der Echtumgebung haben werde.
Danke und Grüße Kermit
Tach!
Ich möchte mir nun für einen bestimmten Zeitraum die gesamte Materialliste anzeigen lassen mit der Anzahl der in diesem Zeitraum verfügbaren Anzahl des jeweiligen Materials.
Definiere "in dem Zeitraum verfügbar".
Ich kann mir die gesamte Materialliste anzeigen lassen, ich kann mir die Summen der jeweiligen im Einsatz befindlichen Materialien anzeigen lassen aber eine vernünftige Abfrage die mir anzeigt Material 1 nicht im Einsatz daher Anzahl m_gesamtanzahl, Material 2 im Einsatz daher Anzahl (m_gesamtanzahl-mp_anzahl), ... bekomme ich irgendwie nicht hin.
Datenbanken wie MySQL arbeiten mengenorientiert. Man sollte dazu ebenfals in Mengen denken, wenn man die Lösung eines Problems sucht. Du brauchst erstmal die Menge der Projekte in einem bestimmten Zeitraum. Das ist die erste Abfrage und das Ergebnis sollten die betroffenen ProjektIDs sein.
Dann brauchst du aus der Verknüpfungstabelle die Materialien. Hier bin ich mir nicht ganz sicher, ob du alle brauchst oder nur die, die den betroffenen Projekten für den Zeitraum oder vielleicht gar zwar dem Projekt zugeordnet sind, aber im Zeitraum nicht vorkommen. Diese Datenmenge wird jedenfalls so eingeschränkt, dass nur die in der ersten Abfragemenge vorhandenen Material-IDs berücksichtigt werden. Dazu kann man in der WHERE-Klausel ein EXISTS vewenden und darin die erste Abfrage als Subquery einbauen. (Beispiele zu EXISTS gibts im MySQL-Handbuch, im Kapitel zu den Subquerys.) Diese Menge wirst du gruppieren wollen, um die Summen ermitteln zu können.
Zum Schluss fragst du die Materialtabelle ab, gejoint mit der Ergebnismenge der eben grad erarbeiteten Query. Wenn du alle Materialien brauchst, nimm einen Inner Join, sonst einen Left Join. Für den Left Join wirst du die Funktion COALESCE() benötigen, die dir das NULL aus der anderen Query in eine 0 übersetzt, sonst kommt NULL raus und nicht die Gesamtmenge: COALESCE(Feld der anderen Query, 0)
Diese Antwort habe ich nur theoratisch erarbeitet und habe nicht geprüft, welche Fallstricke in der Praxis auftreten können. Es kann durchaus sein, dass man dann einen anderen Weg gehen muss.
Achja, in der Test Umgebung habe ich MySql 5.0.67 - weiß allerdings noch nicht welche Version ich in der Echtumgebung haben werde.
Die ist ja uralt.
dedlfix.
Achja, in der Test Umgebung habe ich MySql 5.0.67 - weiß allerdings noch nicht welche Version ich in der Echtumgebung haben werde.
Die ist ja uralt.
dedlfix.
Sag ja ich habe seit Jahren nichts mehr mit MySql gemacht... ;-)
Danke für die Hinweise werde ich mich mal näher mit beschäftigen und Zeitraum ist die Spanne zwischen p_start und p_end
Grüße Kermit