Unverständliches Join-Ergebnis mit Notlösung

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Unverständliches Join-Ergebnis mit Notlösung

    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:

    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) / 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 
    "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

  • #2
    Also unerwartete Ergebnisse sind bei dem Query zu erwarten, da Du Aggregratsfunktionen benutzt und nicht komplett durch gruppierst.
    Beantworte nie Threads mit mehr als 15 followups...
    Real programmers confuse Halloween and Christmas because OCT 31 = DEC 25

    Kommentar

    Lädt...
    X