Bernd: mysql Abfrage oder Struktur gesucht

Hallo,

Lieferscheine:
LieferscheinID, IndexID, VorgangsID, ...

Lieferscheinartikel
ArtikelID, LieferscheinID, ArtNr, ArtBez, VorgangsID, ...

Lieferscheinmengen
MengenID, ArtikelID, IndexID, Menge, ...

Die Idee dahinter ist, alle Artikel inkl. der _bestellten_ Mengen (nicht der gelieferten Mengen!) lediglich ein mal in der Lieferscheinartikel aufzuführen.

Aber es können ja unzählige Lieferscheine mit _gelieferten_ Teilmengen erstellt werden.

Daher wird für jeden Liefervorgang ein neuer Lieferschein in Tabelle Lieferscheine erstellt.
Das Formular zieht alle möglichen zu liefernden Artikel aus der Tabelle Lieferscheinartikel
und die Mengen hierzu aus der Tabelle Lieferscheinmengen.
Die Mengen sind über die IndexID mit dem Lieferschein verknüpft.

Leider bekomme ich die Abfrage für das Formular aber nicht fehlefrei hin. Immer wieder stimmt es fast. Aber nie ganz korrekt.

Frage: Wie muß die Abfrage lauten?

Frage 2: Ist meine Grundidee sinnvoll oder gibt es eine bessere Idee für die Datenstruktur?

Bernd

  1. Lieferscheinartikel
    ArtikelID, LieferscheinID, ArtNr, ArtBez, VorgangsID, ...

    ArtikelID bezeichnet einen Artikel eindeutig? Dann brauchst du hier keine ArtNr und ArtBez mehr, sofern da das drin steht was ich vermute.
    Oder ist hier die ID dieser Tabelle gemeint? Dann würd ich das Feld anders benennen. Die Artikelbezeichnung kann aus dieser Tabelle aber bestimmt rausfliegen.

    Einen "Lieferscheinartikel" und dann dazu mehrere Lieferscheine find ich nicht intuitiv verständlich. Wie wärs mit sowas hier:
    Eine Tabelle "Bestellungen" hält alles was ein Kunde in einem Vorgang bestellt hat. Dazu halt noch eine die zu einer Bestellung alle Artikel hält.
    In der Lieferscheintabelle steht dann das drin, was von einer Bestellung auch tatsächlich geliefert wurde.

    Also: Eine Bestellung pro Bestellvorgang. Mehrere Artikel pro Bestellung.
    Diese Artikel werden in evtl. mehreren Lieferscheinen geliefert. Der Lieferschein verweist auf die Bestellung und auf den enthaltenen Artikel, mit der gelieferten Menge.

    1. Hi encoder,

      Oder ist hier die ID dieser Tabelle gemeint?

      Ja, ist sie.

      Dann würd ich das Feld anders benennen. Die Artikelbezeichnung kann aus dieser Tabelle aber bestimmt rausfliegen.

      Ist bereits anders benannt.
      Und ja, Bezeichnung und Art.-Nr. führe ich redundant, das hat aber andere Hintergründe. s.u.

      Einen "Lieferscheinartikel" und dann dazu mehrere Lieferscheine find ich nicht intuitiv verständlich. Wie wärs mit sowas hier:
      Eine Tabelle "Bestellungen" hält alles was ein Kunde in einem Vorgang bestellt hat. Dazu halt noch eine die zu einer Bestellung alle Artikel hält.
      In der Lieferscheintabelle steht dann das drin, was von einer Bestellung auch tatsächlich geliefert wurde.

      Jein.
      Ich führe die Artikel ja bewußt redundant. Hat den Hintergrund, dass ich in vielen Fällen den direkten Artikelnachfolger liefere. Daher müssen Berstellung und Lieferung un terschiedlich sein dürfen. Das geht am einfachsten, wenn ich sie redundant führe.

      Nochmal zurück zu meiner Struktur:

      Wie würde ich die Abfrage formulieren müssen?

      Gruß, Bernd

      1. Hi, wie hast du sie denn bisher formuliert? ;-)

        Klingt aber tipp-ins-Blaue nach einer normalen Abfrage mit GROUP BY ueber Bezeichnung oder Artikelnnummer.

        1. Hi, wie hast du sie denn bisher formuliert? ;-)

          Du, ich hab schon "zig" Versuche hinter mir ;-)

          Sauber funktionieren tut es aber immer nur, solange es nur 1 lieferschein ist. Sobald der Index ins Spiel kommt, versuche ich anstelle über JOINS auf die LieferscheinID und ArtikelID (das ist und bleibt alles sehr eindeutig) über die VorgangsID und die IndexID zu joinen. Und da haperts dann immer an anderen Stellen.

            
            
          
          

          Klingt aber tipp-ins-Blaue nach einer normalen Abfrage mit GROUP BY ueber Bezeichnung oder Artikelnnummer.

          Hm, das glaube ich jetzt eher nicht, lasse mich aber gerne überzeugen.

          Gruß, bernd

          1. Hi,

            ich versuche, es nochmal neu formuliert:

            --------------------------------------------------------------
            Die Tabellen:

            Lieferscheine:
            LieferscheinID, IndexID, VorgangsID, Belegart, ...

            Lieferscheinartikel
            ArtikelID, LieferscheinID, ArtNr, ArtBez, VorgangsID, ...

            Lieferscheinmengen
            MengenID, ArtikelID, IndexID, Menge, ...
            --------------------------------------------------------------

            Vorhandene Parameter vor der Query:

            1. LieferscheinID = 3
            2. VorgangsID = 333
            3. IndexID = 2
            4. Belegart = CDE
              -------------------------------------------------------------

            Query:

            Liste mir alle Artikel des Bestellvorgangs (JOIN über VorgangsID und Belegart) auf und zeige mir, ob und oin welcher Anzahl hiervon schon welche geliefert wurden,
            also ein Eintrag in der Lieferscheinmengen-Tabelle existiert (LEFT JOIN über ArtikelID).

            Und die IndexID von Tabelle 3 soll der IndexID der Tabelle 1 entsprechen.
            -------------------------------------------------------------

            Gewünschtes Ergebnis:

            Artnr., Artbez., Belegart, Menge, Sonstiges
            aaa, aaa, CDE, -, -
            bbb, bbb, CDE, 44, sontiger Text 1
            ccc, ccc, CDE, 444, sontiger Text 2
            ddd, ddd, CDE, -, -
            --------------------------------------------------------------

            Und hier eine Testtabelle zum event. anlegen?~~~sql

            CREATE TABLE IF NOT EXISTS lieferscheinartikel (
              ArtikelID int(6) NOT NULL AUTO_INCREMENT,
              LieferscheinID int(6) NOT NULL,
              Artnr varchar(100) NOT NULL DEFAULT '',
              Artbez varchar(150) NOT NULL DEFAULT '',
              VorgangsID int(6) NOT NULL DEFAULT '0',
              PRIMARY KEY (ArtikelID),
              KEY LieferscheinID (LieferscheinID)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

            INSERT INTO lieferscheinartikel (ArtikelID, LieferscheinID, Artnr, Artbez, VorgangsID) VALUES
            (1, 1, 'aaa', 'aaa', 333),
            (2, 1, 'bbb', 'bbb', 333),
            (3, 1, 'ccc', 'ddd', 333),
            (4, 1, 'ddd', 'ddd', 333),
            (5, 2, 'aaa', 'aaa', 333),
            (6, 2, 'bbb', 'bbb', 333),
            (7, 2, 'ccc', 'ddd', 333),
            (8, 2, 'ddd', 'ddd', 333);

            CREATE TABLE IF NOT EXISTS lieferscheine (
              LieferscheinID int(6) NOT NULL AUTO_INCREMENT,
              IndexID int(6) NOT NULL,
              VorgangsID int(6) NOT NULL DEFAULT '0',
              Belegart varchar(3) NOT NULL DEFAULT '',
              PRIMARY KEY (LieferscheinID),
              KEY VorgangsID (VorgangsID)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

            INSERT INTO lieferscheine (LieferscheinID, IndexID, VorgangsID, Belegart) VALUES
            (1, 1, 333, 'ABC'),
            (2, 1, 333, 'CDE'),
            (3, 2, 333, 'CDE');

            CREATE TABLE IF NOT EXISTS lieferscheinmengen (
              MengenID int(6) NOT NULL AUTO_INCREMENT,
              ArtikelID int(6) NOT NULL,
              IndexID int(6) NOT NULL,
              Menge float(10,2) NOT NULL DEFAULT '0.00',
              Sonstiges text NOT NULL,
              PRIMARY KEY (MengenID),
              KEY LieferscheinID (ArtikelID)
            ) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

            INSERT INTO lieferscheinmengen (MengenID, ArtikelID, IndexID, Menge, Sonstiges) VALUES
            (1, 5, 1, 2.00, ''),
            (2, 6, 1, 3.00, ''),
            (3, 7, 1, 3.00, ''),
            (4, 8, 1, 2.00, ''),
            (5, 6, 2, 44.00, 'sontiger Text 1'),
            (6, 7, 2, 444.00, 'sonstiger Text 2');

              
            Wer hilft mir dabei?  
              
            Schöne Grüße, Bernd
            
            1. Hallo, ich schaue es mir mal an, koennte aber noch n Tag dauern. Mein Job als Strandkorbtester nimmt mich sehr in Anspruch. :-)
              Cheers, Frank

              1. Hallo, ich schaue es mir mal an, koennte aber noch n Tag dauern. Mein Job als Strandkorbtester nimmt mich sehr in Anspruch. :-)
                Cheers, Frank

                Boah, was für 'ne Frechheit, diese Antwort!!!! ;-))

                Hallo Frank,

                Es sei Dir gegönnt, und sogar doppelt gegönnt, wenn Du da einen Schritt weiter kommst als ich bisher. Das ganze scheint ja doch nicht so trivial zu sein, wie ich anfangs dachte. Jedenfalls, wenn ich es an der Beteiligunng an meinem Thema messe.

                Urlaube also ruhig noch was weiter und ich freue mich, wenn Du zwischendurch etwas Zeit für mein Abfrageproblem findest. :-)

                Gruß, Bernd

                1. Hi, nachdem ich jetzt mal Zeit gefunden hatte, mir die Sache mal anzuschauen ...

                  • u.a. deine Beispieldaten ergeben keinen Sinn ... du hast fuer LieferscheinId 3 keine Lieferscheinartikel

                  • dein Datenmodell passt auch nicht wirklich zu folgendem Anwendungsfall

                  Liste mir alle Artikel des Bestellvorgangs (JOIN über VorgangsID und Belegart) auf und zeige mir, ob und oin welcher Anzahl hiervon schon welche geliefert wurden

                  • die Existenz einer Sinnhaftigkeit von IndexID moechte ich mal stark anzweifeln
                  • dito fuer die Tabelle "Lieferscheinartikel"

                  Loesung: Ab zurueck ans Reissbrett.

                  Du hast Bestellvorgaenge (z.b. identifiziert durch Bestellnummer, bei dir wahrscheinlich "VorgangsID", fein). Dazu sollte es eine Tabelle "Bestellartikel" geben, welche "ArtNr" mit (oder ohne) Menge zu einer VorgangsID zuordnet.

                  Dann ist die Abfrage einfach: Liste mir alle Artikel einer Bestellung die geliefert haetten werden sollen.

                  Weiters hast du deine Tabelle Lieferscheine welche die Belege (was auch immer "CDE" bedeuten mag) zu einer Bestellung (VorgangsId) in Beziehung setzen. Lieferscheine haben auch eine technische ID (LieferscheinID).
                  Vorausgesetzt das ein Lieferschein immer zu einer Bestellung gehoert, aber eine Bestellung mehrere Lieferscheine (Lieferungen) haben kann.
                  Weiters gibt es es eine Tabelle Lieferscheinmengen. Lieferscheinmengen verweist auf LieferscheinID (welche wiederum eindeutig auf VorgangsID verweist) und auf ArtNr und beinhaltet zusaetzlich einfach die gelieferte Menge.

                  Damit wird die Abfrage dann auch einfach(er)

                    
                  SELECT B.VorgangsID, B.ArtNr, SUM(BA.Menge) AS MengeBestellt, SUM(LM.Menge) AS MengeGeliefern, GROUP_CONCAT(LM.Sonstiges)  
                     FROM Bestellvorgaenge B  
                     INNER JOIN BestellvorgaengeArtikel BA ON B.VorgangID = BA.VorgangID  
                     LEFT JOIN Lieferscheine L ON L.VorgangID = B.VorgangID  
                     LEFT JOIN Lieferscheinmengen LM ON LM.LieferscheinID = L.LieferscheinID AND LM.ArtNr = BA.ArtNr  
                     GROUP BY VorgangsID, ArtNr  
                  
                  

                  Uebrig bleibt das Problem das fuer manche bestellte ArtNr evt. Ersatzartikel mit anderer ArtNr geliefert werden. Da loest du einfach damit in dem du in Lieferscheinmengen eine Spalte "ErsetztArtNr" einfuegst oder diese Verknuepfungen in einer separaten Tabelle speicherst, quasi nur ArtNr zu ArtNr.

                  Ich hoffe die Infos helfen dir weiter.

                  Cheerio aus der Kararibik :-)
                  Frank