Hallo,
ich habe ein etwas komplexeres Problem, das ich zwar (scheinbar) lösen konnte, jedoch nur über einen Umweg. Desweiteren verstehe ich es nicht so ganz und hoffe, dass mir jemand
a) das ganze verständlich erklären oder es
b) besser / schöner lösen kann
Gegebenheit:
1. Eine Tabelle mit Warengruppen als Nested Set
2. Eine Tabelle mit Hersteller- und Warengruppen-spezifischen Kunden-Rabatten
Daneben natürlich noch Tabellen mit den Herstellern, den Kunden, Artikeln, globalen Rabattgruppen usw., die aber hier keine Rolle spielen.
Prinzip:
Einem Kunden können in jeder Warengruppe Herstellerabhängige Rabatte vergeben werden. Diese werden in der Tabelle 2 kundenrabatte gespeichert.
Beispiel:
Kunde K_1 bekommt in der Warengruppe WG_1 für den Hersteller H_1 3 % Rabatt; in der WG_1 für den Hersteller H_2 6 % Rabatt usw.
Problem:
Ich möchte für den Kunden K_X alle Warengruppen als Baumstruktur ausgeben, wobei bei jeder Warengruppe vermerkt werden soll, ob hier Rabatte für diesen Kunden hinterlegt sind oder nicht.
Tabellen-Struktur (relevante Felder):
warengruppen: id, lft, rgt, bez, ...
kundenrabatte: id, hersteller_id, kunden_id, warengruppen_id, rabatt
Abfrage:
"COUNT(kr_hersteller_id) AS vergebene_rabatte" ist die erwähnte Notlösung.
Denn (logischer Weise) werden die Ergebniszeilen aus der Tabelle kundenrabatte beim ersten COUNT (AS level) addiert.
Notlösung:
Mit dem zweiten COUNT (AS vergebene_rabatte) erhalte ich nur die Anzahl der Zeilen, die in der Tabelle kundenrabatte gefunden wurden.
Als Notbehelf subtrahiere ich dann mit PHP "vergebene_rabatte" von "level", addiere 1 hinzu und erhalte das (ursprünglich) richtige "Level" der Warengruppe (auf welches ich nicht verzichten kann, da nur in bestimmten Warengruppen-Ebenen Rabatte vergeben werden können).
Suche und Fragen:
Ich habe viel herumgespielt, bis ich zu dieser Lösung kam. Allerdings konnte ich keine (funkionierende) Möglichkeit entdecken, bei der der erste COUNT die Ergebniszeilen aus der Tabelle kundenrabatte unbeachtet lässt.
1. Gibt es nun eine Möglichkeit, auf den Notbehelf mit PHP zu verzichten und gleich das richtige Ergebnis zu erhalten? Die Anzahl der Ergebniszeilen in der Tabelle kundenrabatte ist hierbei irrelevant. Entscheidend ist nur, ob Zeilen vorhanden sind oder nicht, also NULL oder nicht NULL. (Wobei die Anzahl natürlich ideal wäre.)
2. Wie sieht es bei der oben stehenden Query mit der Perfomance aus? Es gibt momentan 518 Warengruppen, 29 Hersteller und knapp über 31000 Kunden. Bei meinen Versuchen habe ich 20 Kunden in jeweils 40 verschiedenen Warengruppen zu jeweils 10 Herstellern Rabatte vergeben. Insgesamt also 8000 Datensätze in der Tabelle kundenrabatte; 400 pro Kunde.
Anmerkung: Der Baum bzw. die Abfrage wird immer nur pro Kunde ausgeführt.
Schönen Dank fürs Lesen,
pb
ich habe ein etwas komplexeres Problem, das ich zwar (scheinbar) lösen konnte, jedoch nur über einen Umweg. Desweiteren verstehe ich es nicht so ganz und hoffe, dass mir jemand
a) das ganze verständlich erklären oder es
b) besser / schöner lösen kann
Gegebenheit:
1. Eine Tabelle mit Warengruppen als Nested Set
2. Eine Tabelle mit Hersteller- und Warengruppen-spezifischen Kunden-Rabatten
Daneben natürlich noch Tabellen mit den Herstellern, den Kunden, Artikeln, globalen Rabattgruppen usw., die aber hier keine Rolle spielen.
Prinzip:
Einem Kunden können in jeder Warengruppe Herstellerabhängige Rabatte vergeben werden. Diese werden in der Tabelle 2 kundenrabatte gespeichert.
Beispiel:
Kunde K_1 bekommt in der Warengruppe WG_1 für den Hersteller H_1 3 % Rabatt; in der WG_1 für den Hersteller H_2 6 % Rabatt usw.
Problem:
Ich möchte für den Kunden K_X alle Warengruppen als Baumstruktur ausgeben, wobei bei jeder Warengruppe vermerkt werden soll, ob hier Rabatte für diesen Kunden hinterlegt sind oder nicht.
Tabellen-Struktur (relevante Felder):
warengruppen: id, lft, rgt, bez, ...
kundenrabatte: id, hersteller_id, kunden_id, warengruppen_id, rabatt
Abfrage:
PHP-Code:
SELECT wg2.*,
COUNT(wg2.id) AS level,
COUNT(kr.hersteller_id) AS vergebene_rabatte,
wg1.id AS gid,
(wg2.rgt - wg2.lft - 1) / 2 AS unterpunkte
FROM warengruppen wg1
LEFT JOIN
warengruppen wg2 ON (wg2.lft BETWEEN wg1.lft AND wg1.rgt)
LEFT JOIN
kundenrabatte kr ON kr.warengruppen_id = wg1.id AND kr.kunden_id = 5
GROUP BY wg2.lft
Denn (logischer Weise) werden die Ergebniszeilen aus der Tabelle kundenrabatte beim ersten COUNT (AS level) addiert.
Notlösung:
Mit dem zweiten COUNT (AS vergebene_rabatte) erhalte ich nur die Anzahl der Zeilen, die in der Tabelle kundenrabatte gefunden wurden.
Als Notbehelf subtrahiere ich dann mit PHP "vergebene_rabatte" von "level", addiere 1 hinzu und erhalte das (ursprünglich) richtige "Level" der Warengruppe (auf welches ich nicht verzichten kann, da nur in bestimmten Warengruppen-Ebenen Rabatte vergeben werden können).
Suche und Fragen:
Ich habe viel herumgespielt, bis ich zu dieser Lösung kam. Allerdings konnte ich keine (funkionierende) Möglichkeit entdecken, bei der der erste COUNT die Ergebniszeilen aus der Tabelle kundenrabatte unbeachtet lässt.
1. Gibt es nun eine Möglichkeit, auf den Notbehelf mit PHP zu verzichten und gleich das richtige Ergebnis zu erhalten? Die Anzahl der Ergebniszeilen in der Tabelle kundenrabatte ist hierbei irrelevant. Entscheidend ist nur, ob Zeilen vorhanden sind oder nicht, also NULL oder nicht NULL. (Wobei die Anzahl natürlich ideal wäre.)
2. Wie sieht es bei der oben stehenden Query mit der Perfomance aus? Es gibt momentan 518 Warengruppen, 29 Hersteller und knapp über 31000 Kunden. Bei meinen Versuchen habe ich 20 Kunden in jeweils 40 verschiedenen Warengruppen zu jeweils 10 Herstellern Rabatte vergeben. Insgesamt also 8000 Datensätze in der Tabelle kundenrabatte; 400 pro Kunde.
Anmerkung: Der Baum bzw. die Abfrage wird immer nur pro Kunde ausgeführt.
Schönen Dank fürs Lesen,
pb
Kommentar