SQL Abfrage funktioniert nicht mehr nach Update
Hallo zusammen,
nach unserem letzten Update der Datenbank (Sage auf MS SQL Server 2008) läuft eine SQL Abfrage nicht mehr.
Die Abfrage komplett ist wie folgt:
Vorher lief diese Formel super und hat auch immer genau einen Wert zu einer Artikelnummer herausgeworfen. Wenn man nun die Unterabfragen ( Codezeilen 4 - 11)
rausnimmt funktioniert das ganze zwar, allerdings dann ohne die Preise. Beim versuch das ganze neu aufzubauen hängt das ganze dann daran, das man nur Artikel angezeigt bekommt, ohne Lagerbestand, oder mit dem Filter auf Lagerbestand > 0 garnichts mehr angezeigt bekommt.
Die Fehlermeldung die man derzeit bekommt lautet:
Die Unterabfrage hat mehr als einen Wert zurückgegeben. Das ist nicht zulässig, wenn die Unterabfrage auf .....
Ich verweifel hier grad ein wenig an dem Ding. Ich hab schon öfter mal ein wenig mit SQL gearbeitet, aber die Unterabfragen und die Ergebnisse die ich in den letzten 1,5 Tagen mit dieser Herausforderung hab, sind mir doch noch etwas zu viel.
Gibt es hier ein paar versierte SQL Spezis die mir hier ein wenig zur Hand gehen können?
Bin über jede hilfe froh und dankbar!!
Gruß Tailz
nach unserem letzten Update der Datenbank (Sage auf MS SQL Server 2008) läuft eine SQL Abfrage nicht mehr.
Die Abfrage komplett ist wie folgt:
SELECT dbo.KHKArtikel.Artikelnummer, dbo.KHKArtikelgruppen.Bezeichnung AS Gruppe, dbo.KHKArtikel.Bezeichnung1 AS Bez1,
dbo.KHKArtikel.Bezeichnung2 AS Bez2, dbo.KHKArtikelVarianten.Lagerbestand AS Bestand, dbo.KHKArtikelVarianten.MittlererEK AS MEK,
(SELECT KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler' AND
KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS Haendler,
(SELECT KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Endkunde' AND
KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS Endkunde, dbo.KHKArtikel.Dispoformel AS Dispo,
dbo.KHKArtikel.USER_WebPromotion AS Highlight, dbo.KHKArtikelBezeichnung.Langtext AS Langtext
FROM dbo.KHKArtikel INNER JOIN
dbo.KHKArtikelgruppen ON dbo.KHKArtikel.Artikelgruppe = dbo.KHKArtikelgruppen.Artikelgruppe LEFT OUTER JOIN
dbo.KHKArtikelBezeichnung ON dbo.KHKArtikel.Artikelnummer = dbo.KHKArtikelBezeichnung.Artikelnummer LEFT OUTER JOIN
dbo.KHKArtikelVarianten ON dbo.KHKArtikel.Artikelnummer = dbo.KHKArtikelVarianten.Artikelnummer
WHERE (dbo.KHKArtikelVarianten.Lagerbestand > 0) OR
(dbo.KHKArtikel.Dispoformel = 11)
Vorher lief diese Formel super und hat auch immer genau einen Wert zu einer Artikelnummer herausgeworfen. Wenn man nun die Unterabfragen ( Codezeilen 4 - 11)
rausnimmt funktioniert das ganze zwar, allerdings dann ohne die Preise. Beim versuch das ganze neu aufzubauen hängt das ganze dann daran, das man nur Artikel angezeigt bekommt, ohne Lagerbestand, oder mit dem Filter auf Lagerbestand > 0 garnichts mehr angezeigt bekommt.
Die Fehlermeldung die man derzeit bekommt lautet:
Die Unterabfrage hat mehr als einen Wert zurückgegeben. Das ist nicht zulässig, wenn die Unterabfrage auf .....
Ich verweifel hier grad ein wenig an dem Ding. Ich hab schon öfter mal ein wenig mit SQL gearbeitet, aber die Unterabfragen und die Ergebnisse die ich in den letzten 1,5 Tagen mit dieser Herausforderung hab, sind mir doch noch etwas zu viel.
Gibt es hier ein paar versierte SQL Spezis die mir hier ein wenig zur Hand gehen können?
Bin über jede hilfe froh und dankbar!!
Gruß Tailz
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 224846
Url: https://administrator.de/contentid/224846
Ausgedruckt am: 26.11.2024 um 12:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo Tailz,
ich bin ja kein Freund von solchen Unterabfragen im SELECT-Teil.
Warum bindest Du diese nicht per LEFT JOIN mit ein?
Und im SELECT-Teil a.einzelpreis AS Haendler und b.einzelpreis AS Endkunde.
G Jörg
ich bin ja kein Freund von solchen Unterabfragen im SELECT-Teil.
Warum bindest Du diese nicht per LEFT JOIN mit ein?
LEFT JOIN (SELECT KHKPreislistenArtikel.Artikelnummer AS Artkelnummer, KHKPreislistenArtikel.Einzelpreis AS Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler') a
ON KHKArtikel.Artikelnummer = a.Artikelnummer
LEFT JOIN (SELECT KHKPreislistenArtikel.Artikelnummer AS Artkelnummer, KHKPreislistenArtikel.Einzelpreis AS Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Endkunde') b
ON KHKArtikel.Artikelnummer = b.Artikelnummer
Und im SELECT-Teil a.einzelpreis AS Haendler und b.einzelpreis AS Endkunde.
G Jörg
Hallo Tailz,
in mindestens einer Deiner beiden Unterabfragen für die Preise bekommst Du mehrere Zeilen zurück und das ist an dieser Stelle nicht zulässig.
Umgehen kannst Du das, indem Du ein " top (1) " hinter das SELECT in der Unterabfrage schreibst. Dann bringt die Unterabfrage sicher nur eine Zeile zurück und funktioniert:
Aber wenn es zu einem Artikel mehrere Händler oder mehrere Kunden gibt, dann ist das Ergebnis mit Sicherheit unbefriedigend, weil Du eben zufällig einen Händler und zufällig einen Kunden angezeigt bekommst. Den Zufall könntest Du mit einem "ORDER BY" noch beeinflussen, damit wenigstens immer derselbe Preis gewählt wird:
Du soltest Dir also überlegen, was der Zweck hinter Deiner Abfrage ist. Möchtest Du den höchsten/niedrigesten oder vielleicht den Durchschnittspreis angezeigt bekommen? Dann sollte die Unterabfrage eine Aggregatfunktion enthalten. Dann brauchst Du das "top (1)" nicht, dann kommt auch nur ein Datensatz zurück. Wäre dann etwa so:
Und letzten Endes kannst Du auch alle möglichen Kombinationen von Händler- und Kundenpreisen erzeugen:
Wobei dann sicher noch die Namen des Händlers und des Kunden interessant wären.
Gruß, Mad Max
Edit: Die letzte Möglichkeit ist quasi dasselbe wie vom Tarzan. Aber vorsicht, da bekommst Du ein Kreuzprodukt, das mußt Du Dir überlegen, ob Du das willst.
in mindestens einer Deiner beiden Unterabfragen für die Preise bekommst Du mehrere Zeilen zurück und das ist an dieser Stelle nicht zulässig.
Umgehen kannst Du das, indem Du ein " top (1) " hinter das SELECT in der Unterabfrage schreibst. Dann bringt die Unterabfrage sicher nur eine Zeile zurück und funktioniert:
(SELECT top (1) KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler' AND KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS Haendler,
Aber wenn es zu einem Artikel mehrere Händler oder mehrere Kunden gibt, dann ist das Ergebnis mit Sicherheit unbefriedigend, weil Du eben zufällig einen Händler und zufällig einen Kunden angezeigt bekommst. Den Zufall könntest Du mit einem "ORDER BY" noch beeinflussen, damit wenigstens immer derselbe Preis gewählt wird:
(SELECT top (1) KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler' AND KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer
ORDER BY KHKPreislisten.ID) AS Haendler,
Du soltest Dir also überlegen, was der Zweck hinter Deiner Abfrage ist. Möchtest Du den höchsten/niedrigesten oder vielleicht den Durchschnittspreis angezeigt bekommen? Dann sollte die Unterabfrage eine Aggregatfunktion enthalten. Dann brauchst Du das "top (1)" nicht, dann kommt auch nur ein Datensatz zurück. Wäre dann etwa so:
(SELECT max (KHKPreislistenArtikel.Einzelpreis)
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler' AND KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS Haendler,
Und letzten Endes kannst Du auch alle möglichen Kombinationen von Händler- und Kundenpreisen erzeugen:
SELECT dbo.KHKArtikel.Artikelnummer, dbo.KHKArtikelgruppen.Bezeichnung AS Gruppe, dbo.KHKArtikel.Bezeichnung1 AS Bez1,
dbo.KHKArtikel.Bezeichnung2 AS Bez2, dbo.KHKArtikelVarianten.Lagerbestand AS Bestand, dbo.KHKArtikelVarianten.MittlererEK AS MEK,
HaendlerTab.Einzelpreis AS Haendler,
EndkundeTab.Einzelpreis AS Endkunde,
dbo.KHKArtikel.Dispoformel AS Dispo,
dbo.KHKArtikel.USER_WebPromotion AS Highlight, dbo.KHKArtikelBezeichnung.Langtext AS Langtext
FROM dbo.KHKArtikel INNER JOIN
dbo.KHKArtikelgruppen ON dbo.KHKArtikel.Artikelgruppe = dbo.KHKArtikelgruppen.Artikelgruppe LEFT OUTER JOIN
dbo.KHKArtikelBezeichnung ON dbo.KHKArtikel.Artikelnummer = dbo.KHKArtikelBezeichnung.Artikelnummer LEFT OUTER JOIN
dbo.KHKArtikelVarianten ON dbo.KHKArtikel.Artikelnummer = dbo.KHKArtikelVarianten.Artikelnummer
outer apply (SELECT KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Haendler' AND KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS HaendlerTab
outer apply (SELECT KHKPreislistenArtikel.Einzelpreis
FROM KHKPreislistenArtikel, KHKPreislisten
WHERE KHKPreislistenArtikel.ListeID = KHKPreislisten.ID AND KHKPreislisten.Bezeichnung = 'Endkunde' AND KHKArtikel.Artikelnummer = KHKPreislistenArtikel.Artikelnummer) AS EndkundeTab
WHERE (dbo.KHKArtikelVarianten.Lagerbestand > 0) OR
(dbo.KHKArtikel.Dispoformel = 11)
Wobei dann sicher noch die Namen des Händlers und des Kunden interessant wären.
Gruß, Mad Max
Edit: Die letzte Möglichkeit ist quasi dasselbe wie vom Tarzan. Aber vorsicht, da bekommst Du ein Kreuzprodukt, das mußt Du Dir überlegen, ob Du das willst.