Komplexe SQL Abfrage über mehrere Tabellen mit Null werten

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Komplexe SQL Abfrage über mehrere Tabellen mit Null werten

    Hallöchen,

    ich bräuchte mal eure Hilfe bzw. einen Denkanstoß wie man das am Besten realisieren kann:

    Ich habe eine MSSQL Datenbank mit 4 Tabellen.

    Tabelle1= Artikelnummern
    Tabelle2=Artikeldetails
    Tabelle3=Artikelattribute
    Tabelle4=Preise

    Ich muss jetzt über einen SQL-Befehl alle Artikelnummern aus Tabelle1 laden. Diese Artikelnummern werden dann verknüpft mit der Bestellnummer aus der Tabelle2. Aus Tabelle3 gesellt sich dann noch die Warengruppe dazu.
    Das ganze würde sich ja folgendermaßen lösen lassen:

    SQL-Abfrage

    1. ​sqlquerystring = "Select A.id,B.ordernumber,C.WGR " &
    2. "FROM " &
    3. "s_articles as A " &
    4. "join s_articles_details as B " &
    5. "ON A.id=B.articleID " &
    6. "join s_articles_attributes as C " &
    7. "ON A.id=C.articleID" &


    Jetzt habe ich in Tabelle4 aber folgendes stehen:
    ID | Customernumber | ArticleID | Price

    Also brauche ich jetzt in der oben genannten Selektion noch (falls vorhanden) für jeden Artikel den Preis aus Tabelle4 für Kundennummer "103408".

    Das funktioniert auch mit folgendem Select:

    SQL-Abfrage

    1. ​ sqlquerystring = "Select A.id,B.ordernumber,C.WGR,D.price " &
    2. "FROM " &
    3. "s_articles as A " &
    4. "join s_articles_details as B " &
    5. "ON A.id=B.articleID " &
    6. "join s_articles_attributes as C " &
    7. "ON A.id=C.articleID " &
    8. "left join uni_directprices as D " &
    9. "ON A.id=D.articleId where D.customernumber='103408'"


    Hier habe ich jetzt allerdings NUR die Artikel drin stehen wo der Kunde in der Tabelle "directprices" auch einen Preis hinterlegt hat (was ja klar ist).
    Da ich aber später noch andere Preistabellen abfragen muss wenn in der "uni_directprices also Tabelle4" kein Preis gefunden wurde, bräuchte ich natürlich alle Artikelnummern angezeigt auch wenn diese nicht für den Kunden in
    der Tabelle4 hinterlegt sind.

    Die abfrage muss später so aussehen:
    Hole alle Artikel aus der Hauptartikeltabelle und ergänze mir dazu ein paar spezifische Daten aus ein paar anderen Tabellen.
    Zum Schluss hole mir den Preis aus Tabelle 4. Wenn dort kein Preis hinterlegt ist, hole mir den Preis aus Tabelle5. Wenn dort auch kein Preis ist, dann den Preis aus Tabelle6 ermitteln.

    Das ganze wird aktuell in ein Dataset geladen. Erst hatte ich eine Schleife gebaut die einmal über alle Artikel drüber rennt und dann die Sqlabfragen macht wie ich sie brauche aber bei 20000 Artikeln sind das Pro Zeile dann 3 oder 4 SQL-Abfragen.
    Ich denke das ist nicht Sinn und Zweck des ganzen :P


    Vielen Dank für eure Hilfe!
    Hallo @Holistiker
    Das sieht nach eine Abfrage mit einem LEFT-Join aus.
    Der Unterschied zu einem normalen Join ist, dass du trotzdem alle Artikelnummern bekommst, obwohl dazu kein Preis gefunden wurde.
    So könntest du nach einander einen LEFT-Join auf deine Preistabellen machen.

    Gibt es denn zu jedem Artikel nur einen Preis oder kann in Preistabelle 1 und 2 ein Preis für Artikel xyzzy stehen?

    Holistiker schrieb:

    Tabelle1= Artikelnummern
    Tabelle2=Artikeldetails
    Tabelle3=Artikelattribute
    Tabelle4=Preise
    Ist ja ein komisches Datenmodell: Artikelnummern, Artikeldetails, Artikelattribute, ArtikelPreise gibts, aber keine Artikel?

    Kannst du vlt. das ER-Diagramm deiner DB (oder zumindest des relevanten Teils) posten?
    Im MS-Sql-ManagmentStudio kann man "Diagramm erstellen" klicksen, und dem Diagramm dann alle relevanten Tabellen zufügen.
    Aus dem ER-Diagramm sind dann alle Spalten, und auch die Relationen zw. den Tabellen ersichtlich - dassis wichtig für die Formulierung von Sql-Abfragen.
    Also die Preisgestaltung ist eigentlich so:

    Artikel gehört zu Warengruppe A dieser Artikel hat 6 Verschiedene Verkaufspreise (VK1 bis VK6)
    Der Kunde wird nun grundsätzlich in eine VK-Gruppe eingeordnet zb. VK2 <-Damit würde der Kunde für alle Artikel den VK2 bekommen.

    DIe Abfrage ist jetzt so:
    Wenn der Kunde einen direkten Preis für den Artikel hat dann steht dieser in Tabelle1.
    Hat der Kunde in Tabelle1 keinen Preis muss geschaut werden ob für diesen Kunden in Tabelle2 eine VK-Gruppe für eine bestimmte Warengruppe festgelegt ist. (Kunde kann z.B. für Warengruppe A den VK4 bekommen aber für alle anderen die Standardmäßig hinterlegte (im Beispiel VK2)).
    Ist in beiden Tabellen kein Kundenspezifischer Preis hinterlegt, wird der VK2 Preis aus der Artikeltabelle geladen der dort dann dem Artikel direkt zugeordnet ist.

    Habe die Abfrage jetzt gerade mal verkürzt aber ich bekomme leider trotzdem die "NULL" Werte nicht angezeigt.

    SQL-Abfrage

    1. "Select A.id,D.price " &
    2. "FROM " &
    3. "s_articles as A " &
    4. "left Join uni_directprices as D " &
    5. "ON A.id=D.articleId where D.customernumber='103408'"



    //Edit sorry hab die Antwort von EDR erst nach dem Posten gesehen. Das Datenmodell kommt aus dem Shopware bereich und ist dort Standard. In der Tabelle1 sind quasi die Artikel drin die du suchst. Dort werden die Artikel angelegt und die ID von diesen zieht sich dann so durch.
    Das ERM ist hier zu finden developers.shopware.com/develo…ntity-relationship-model/
    Die Preistabellen mit den Warengruppen bzw. Direktpreisen für Artikel ist eine eigene Anpassung.
    Ich habe folgendes in MySQL getestet:
    Tabelle article mit id und name, price1 mit article_id und price und price2 identisch zur ersten Preistabelle.

    In der Artikeltabelle stehen drei Artikel. Der Preis zum ersten Artikel steht in price1 und die anderen Preise in price2.
    Ich bekomme dann dieses Ergebnis. Das sieht mir nach dem aus, was du haben möchtest.



    Was bekommst du denn statt den NULL-Einträgen?

    Edit: Vielleicht ist es in MSSQL ein LEFT OUTER JOIN?

    SQL-Abfrage

    1. ​FROM table1 t1 LEFT OUTER JOIN table2 t2
    2. ON t1.a = t2.c

    LaMiy schrieb:

    Vielleicht ist es in MSSQL ein LEFT OUTER JOIN
    Es gibt keinen Unterschied zwischen LEFT JOIN und LEFT OUTER JOIN.
    OUTER ist ein impliziter optionaler Parameter, der einfach als syntaktisches Pendant zum INNER JOIN existiert (der wiederum ist nicht optional).
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @Holistiker
    Ist doch klar, dass die NULL Werte nicht drinstehen, wenn du die where-Klausel benutzt :)
    Das kannst du umgehen, indem du ein or D.customernumber is NULL anhängst.



    Das Ergebnis musst du dir dann noch irgendwie schön zusammenbasteln. (Vielleicht ähnlich wie ich das oben in meiner Beispielabfrage gemacht habe)