mySQL 5.5: Welcher Lieferant bietet Artikel nicht als günstigster Lieferant an

oliverb

Mitglied
Hallo,

ich nutze mySQL 5.5, bin neu hier in diesem Forum und benötige bitte Eure Hilfe. Ich habe die folgende Datenbankstruktur:

Table "Preise" (80 Lieferanten)
##########################
artikel_short = interne Artikelnummer
supplier_productID = Lieferanten Artikelnummer
wawiID = interne Lieferantennummer
stock = Lagerbestand des Lieferanten
nettoEK = Einkaufspreis

Table „Artikel" (130 TSD)
##########################
artikel_short = interne Artikelnummer
description = Artikelbezeichnung
…..

Ich verzweifele daran einen SELECT zu bauen, der ausschließlich Artikel beinhaltet, welche ein Lieferant (wawiID) NICHT als günstigster Anbieter einstellt. Zusätzlich sollte in dem SELECT ein Feld generiert werden, das den Differenzbetrag zum günstigsten Lieferant darstellt und optional ein weiteres Feld, welches die entsprechende Platzierung des Lieferanten und seines Preises darstellt.

Die folgenden Spalten sollten ausgegeben werden:
###########################################
supplier_productID = Lieferanten Artikelnummer
description = Artikelbezeichnung
nettoEK = Angebotener Preis des Lieferanten
difference = Differenzbetrag zum günstigsten Lieferanten
placement = Platzierung des Artikels (Sortierung nach günstigstem Lieferant aufsteigend)


Das für mich Schwierige daran ist alles in einen SELECT mit entsprechenden SUBSELECTS zu bekommen.Diese Daten möchte ich nämlich jedem Lieferanten als Datei, ausschließlich mit seinen eigenen Artikeln zur Verfügung stellen!

Vielen Dank schon mal vorab für Eure Ideen...
 
Zuletzt bearbeitet:
Es könnten schlimmere Anforderungen sein

Hier mal mein Test: http://sqlfiddle.com/#!2/9189e1/1
SQL:
SELECT 
  prank.supplier_productid,
  a.description,
  prank.nettoek,
  prank.nettoek - pmin.nettoek AS diff,
  prank.rank AS placement
FROM 
  -- Daten inkl. Rang
  (
    SELECT 
        @rank := IF(@last_a = pr.artikel_short, @rank+1, 1) AS rank, 
        pr.*, 
        @last_a := pr.artikel_short AS artikel_short_save 
    FROM preise pr, (SELECT @last_a:=0, @rank :=0) vars 
    ORDER BY pr.artikel_short, pr.nettoEK
  ) prank,
  -- Kleinster nettoek pro Artikel
  (
    SELECT pm.artikel_short, MIN(pm.nettoek) AS nettoek 
    FROM preise pm 
    GROUP BY pm.artikel_short
  ) pmin,
  -- Artikel Zusatzinfos
  artikel a
WHERE 
  -- Den ersten Rang ausschliessen
  prank.rank != 1
  -- JOINS
  AND prank.artikel_short = pmin.artikel_short
  AND prank.artikel_short = a.artikel_short
 ;
 
Wow, danke für die fixe Antwort. Scheint zu funktionieren. Allerdings spielt bei den LIVE-Daten mein Server noch nicht ganz mit. Muss den jetzt erst mal tunen:... :)

#1104 The SELECT would examine more than MAX_JOIN_ROWS. Check your WHERE and use SET
MAX_JOIN_SIZE=1 bzw. SQL_BIG_SELECTS=#
 
Zuletzt bearbeitet:
Ich habe leider noch noch zwei kurze Nachfragen:

Frage 1
An welcher Stelle baue ich es am Besten ein, dass bei der Ausgabe nur die Artikel eines bestimmten Lieferanten (wawiID) dargestellt werden?

Frage 2
Mein Server/Provider verlangt, dass ich vor dem Absenden des eigentlichen SELECTS "den Befehl SET MAX_JOIN_SIZE=1;" absende. Dies deaktiviert für den Rest der Session die gesetzte MAX_JOIN_SIZE bzw. setzt diese auf unbegrenzt. Wenn ich das nicht mache erhalte ich die obere Fehlermeldung aus meinem vorheringen Post. Funktioniert das dann also nur als ROUTINE bzw. STORED PROCEDURE? Meine PHP-Klasse kann scheinbar nur einen Befehl pro Session absenden... :-(
 
Zur Frage 1:
Einfach unten im WHERE ergänzen
SQL:
 AND prank.wawiid = 1[/code>

Zur Frage 2:
Leider habe ich keine Antwort für dich. Ich habe seit 2 Jahren kein PHP mehr programmiert und mit DB-Servern kenne ich mich auch nicht aus.
 
Ich habe das ganze jetzt per STORED-PROCEDURE gelöst. Das klappt mit dem Aufruf wunderbar. Bei der Sichtung der Ergebnisse ist mir aber noch folgende Kleinigkeit aufgefallen.

Leider habe ich durch den Artikelimport der Lieferanten auch Artikel ohne Preis. Im Table "Preise" stehen diese Artikel mit 0.00 EUR, da manche Lieferanten leider Ihre gesamte Artikelliste übertragen. Das muss ich jetzt noch abfangen, da sonst ja der Rang und die Differenzberechnung zum günstigsten Artikel nicht passt. Die besagten Artikel mit einem nettoEK=0.00 sollen daher einfach von der Berechnung ausgeschlossen werden.

Kannst Du mir bitte kurz sagen an welcher Stelle ich das noch einbauen muss?!
 
Hallo oliverb,

wenn du weitere Einschränkungen hast, sollten die ebenfalls in die WHERE-Konditionen angehängt werden. Ggf. kann man auch mit NOT arbeiten. In diesem Fall sieht es günstig aus, wenn du das in den Sub-SELECT einbaust, der auf die kleinsten Netto-Preise eingeht:

SQL:
  -- Kleinster nettoek pro Artikel
 (
   SELECT pm.artikel_short, MIN(pm.nettoek) AS nettoek
   FROM preise pm
   GROUP BY pm.artikel_short
   WHERE pm.nettoek != 0.0
 ) pmin,

Grüße
 
Die Berechnung des kleinsten nettoEK funktioniert nun. Danke dafür!

Was Einzige was jetzt noch nicht funktioniert ist die Rangberechnung, da aktuell die erste Platzierung der Datensatz mit dem Preis von 0.0 EUR ist. Vielleicht hat jemand hierzu ja noch eine Idee.
 
Zuletzt bearbeitet:
Zurück