Having Count auf Distinct mit mehreren Spalten möglich?

beuber

Benutzer
Beiträge
5
Hallo,

ich würde mir gerne aus einer Tabelle 'Lagerbestände', alle Lagerorte ausgeben auf denen unterschiedliche Artikel liegen und die Anzahl der unterschiedlichen Artikel mit angeben.
Das Problem hierbei ist, dass es zu einem Artikel auf einem Lagerort zwei Datensätze geben kann, dies liegt an der eingesetzten Software welche die DB verwaltet und hier hab ich keinen Einfluss drauf.
Beispiel:
Lager | Artikel | Menge
C1A | 62005 |20
C1A | 62005 |2

Weiß vielleicht einer wie ich dies hinbekommen könnte?

Hier meine Tabellen:
Tabelle Lagerbestände (ID, Lagerid, ArtikelID, Artikelnummer, Artikelbezeichnung, Menge)
Tabelle Lager ( ID, Bezeichnung, LaggergruppenID, ...)

Die Tabelle Lager wird lediglich benötigt um die Bezeichnung des Lagers angeben zu können.

Mein Versuch:
SELECT DISTINCT B.Lagerid, L.Bezeichnung, B.Artikelnummer
FROM
lagerbestaende B
INNER JOIN
Lager L
ON
B.Lagerid = L.ID
WHERE
B.Menge > 0
GROUP BY B.Lagerid, L.Bezeichnung, B.Artikelnummer
HAVING COUNT (*)>1
ORDER BY
l.bezeichnung

Hier werden mir aber auch Läger angezeigt die keine unterschiedlichen Artikel haben, da die Problematik besteht das auf einem Lagerort ein Artikel auch zwei Datensätze beinhalten kann.
Ich bräuchte in etwa eine Funktion wie HAVING COUNT (DISTINCT B.Lagerid, B.Artikelnummer)>1 => Doch hier kann leider nur eine Spalte mitgegeben werden.
Leider hab ich beim Suchen keine Lösung gefunden.

Bin für jede Gedankenstütze dankbar :)
 
Werbung:
Verstehe ich jetzt erstmal nicht so wirklich, vor allem was das DISTINCT in einem GROUP BY bewirken soll.
Code:
SELECT B.Lagerid, L.Bezeichnung, B.Artikelnummer,count(*) AS Anzahl
FROM
lagerbestaende B
INNER JOIN
Lager L
ON
B.Lagerid = L.ID
WHERE
B.Menge > 0
GROUP BY B.Lagerid, L.Bezeichnung, B.Artikelnummer
HAVING COUNT (*)>1
ORDER BY
l.bezeichnung
Dürfte dir erstmal alles liefern wo mehrere gleiche Artikelnummern im gleichen Lager liegen. Woher weißt du jetzt ob das wirklich unterschiedliche Positionen des selben Artikel im selben Lager sind oder ob der Datensatz von deiner Anwendung "dupliziert" wurde? Ist das Beispiel
Lager | Artikel | Menge
C1A | 62005 |20
C1A | 62005 |2
Jetzt von zwei richtigen Datensätzen oder kommt der zweite Datensatz von deiner Anwendung und ist nicht gewünscht? Wie unterscheidest du hier?
 
Danke für die Antwort.
Stimmt, dass DISTINCT ist komplett überflüssig.
Woher weißt du jetzt ob das wirklich unterschiedliche Positionen des selben Artikel im selben Lager sind oder ob der Datensatz von deiner Anwendung "dupliziert" wurde?
Ich hab mir die Daten in der Datenbank angesehen und dort sind die "doppelten" Einträge zu finden. Zum besseren veständnis, hier einmal die Abfragen und ein Ausschnitt der Ausgabe für das Lager C2A. Hier wird bei Anzahl 2 angezeigt, was an sich auch richtig ist, nur das es keine unterschiedlichen Artikel sind, sondern der selbe Artikel zweimal in der Tabelle Lagerbestände vorhanden ist.

Abfrage:
SELECT B.Lagerid, L.Bezeichnung, B.Artikelnummer,count(*) AS Anzahl
FROM
lagerbestaende B
INNER JOIN
Lager L
ON
B.Lagerid = L.ID
WHERE
B.Menge > 0
GROUP BY B.Lagerid, L.Bezeichnung, B.Artikelnummer
HAVING COUNT (*)>1
ORDER BY
l.bezeichnung

Ausgabe:
1693472106387.png

Abfrage:
SELECT LagerID, Artikelnummer, Einbuchungsdatum, Menge
FROM
Lagerbestaende
WHERE
Lagerid = '2345'
AND
Menge > 0

Ausgabe
1693472298932.png


Jetzt von zwei richtigen Datensätzen oder kommt der zweite Datensatz von deiner Anwendung und ist nicht gewünscht? Wie unterscheidest du hier?
Wie oben zu sehen, sind es richtige Datensätze und somit erwünscht.

PS: Den Code kann ich leider nicht kenntlich machen, wie in deinem Post, da die Funktion unter 'Weitere...' -> 'Code' bei mir einen Fehler auswirft.
 
Lagerid 2345
Es tauchen 2 Datensätze mit gleicher anr auf, da sie ein unterschiedliches Buchungsdatum haben.
Bin nicht sicher, ob Oracle das kann und ob ich dich richtig verstanden hab:
Schau mal nach countdistinct(<myfield>)
 
Danke, ja ich denke du hast mich richtig verstanden. Ich müsste die Zeilen mit gleicher Lagerid und Artikelnummer zusammenfassen unabhängig von den anderen Felder (Einbuchungsdatum, Menge) und darauf dann ein Having Count > 1 anwenden.
Ich hatte bereits sowas wie HAVING COUNT (B.Lagerid, B.Artikelnummer) geteste, aber hier kann leider nur ein Parameter übergeben werden.

COUNTDISTINCT wirft leider den Fehler 'ORA-00904: "COUNTDISTINCT": ungültiger Bezeichner' somit kann Oracle das wohl nicht.
 
Sowas in der Art vielleicht:

Code:
select *
from (
  SELECT b.lagerid, l.bezeichnung, b.artikelnummer,
         count(*) partition by (b.lagerid, b.artikelnummer) AS anzahl
  FROM lagerbestaende B
    JOIN lager l ON b.lagerid = l.id
  WHERE b.menge > 0
) x
WHERE anzahl > 1
ORDER BY bezeichnung;
 
Werbung:
Der Versuch mit 'partition by' hat nicht geklappt. Hier war die Anzahl immer noch fehlerhaft.
Hab das Problem aber mit einer Sub-Abfrage lösen können.
Hier einmal meine Lösung:

SELECT
SUB.KUERZEL,
COUNT(DISTINCT SUB.ARTIKELID)
FROM
(SELECT
L.KUERZEL,
LB.ARTIKELID
FROM
LAGERBESTAENDE LB
INNER JOIN LAGER L ON LB.LAGERID=L.ID
GROUP BY
L.KUERZEL,
LB.ARTIKELID
HAVING
SUM(LB.MENGE)>0) SUB
GROUP BY
SUB.KUERZEL
HAVING
COUNT(DISTINCT SUB.ARTIKELID)>1;

Nochmal vielen Dank für eure Unterstützung.
 
Zurück
Oben