Etwas schwierigere SQL Abfrage

Asiaddor

New Member
Hallo

Ich möchte eine etwas spezielle Information von einer SQL(-Server) Datenbank abfragen.

Die DB hat (vereinfacht) folgenden Inhalt:
Lagerort, Produkt-Nr, Lieferant

Nun möchte ich wissen, welche Lager die selben Produkte vom selben Lieferant haben. Die Abfrage soll mir also nur Produkte zeigen, die in mindestens zwei verschiedenen Lagern vorkommen. Ist sowas mit purem SQL möglich, oder muss ich prozedural im Programm eine Schleife über eine Abfrage machen?

Hab mich mit DISTINCT und GROUP BY Ausdrücken rumgeschlagen, aber nicht das gewünschte erhalten. Kann mir jemand helfen?

Philippe
 
Deine Aussage definiert nicht klar, was du genau sehen willst.
Lager + Produkte?
Produkte + Lieferraten?
Lager + Produkte + Lieferranten?

Umso mehr du anzeigen lässt, desto mehr Dopplungen hast du drin.
Ganz davon abgesehen, das solche Werte nicht in eine Tabelle gehören. Diese Datenbank sollte dringenst normalisiert werden.

Ansonsten eine Möglichkeit wäre, ansatzweise da ran zu kommen was du dir vorstellst:
Code:
SELECT DISTINCT Lager, Produkt
FROM testlager
WHERE Produkt IN (SELECT Produkt
                  FROM testlager 
                  GROUP BY Produkt, Lieferrant
                  HAVING COUNT(Produkt)>=2)
AND Lieferrant IN (SELECT Lieferrant
                  FROM testlager 
                  GROUP BY Produkt, Lieferrant
                  HAVING COUNT(Produkt)>=2);

Natürlich ohne Gewähr ob da in jedem Fall das raus kommt, was man sich erhofft.
 
Hallo Firewire

Vielen Dank für deine Antwort! Die von dir angegebene Abfrage bringt zwar nicht das korrekte Resultat, aber du hast mich auf den richtigen Weg gebracht!! Nun hab ich nach einigem Tüfteln die korrekte Abfrage herausgekriegt! *freu* :)

Wichtig ist, dass der Lagerort pro Produkt analysiert wird. Ich brauche jene Produkte, die:
Subselect 1: Gleiche Nr haben, egal in welchem Lager, aber in min. 2 Lager (auch die selben!)
UND
Subselect 2: Gleiche Nr, nur einmal pro Lager (keine Doppel in einem Lager!)

In anderen Worten: Alle Produkte, die zwar mehrere Lager-IDs zugeteilt haben, aber davon nur jene, bei denen die Lager IDs unterschiedlich sind. Hmm, ich glaube durch den Text versteht mans nicht. Die Abfrage übersteigt eigentlich selbst meine Vorstellungskraft *g* Aber es klappt und wenn ich die beiden Subselects einzeln ausführe, wird mir auch klar, warum.

Code:
SELECT  Lager, [Lieferanten Artikel-Nr], Lieferantenname
FROM SLH_PRODUKTE_remote
WHERE [Lieferanten Artikel-Nr] IN (

SELECT  [Lieferanten Artikel-Nr]
                  FROM SLH_PRODUKTE_remote
                  GROUP BY [Lieferanten Artikel-Nr]
                  HAVING COUNT([Lager])>=2)

AND [Lieferanten Artikel-Nr] IN (
SELECT  [Lieferanten Artikel-Nr]
                  FROM SLH_PRODUKTE_remote
                  GROUP BY [Lieferanten Artikel-Nr], Lager
                  HAVING COUNT([Lager])=1
)

Ach und ja, ist mir schon klar, dass die Tabelle nicht normalisiert ist. Das ist jedoch so gewollt, da es sich um ein Data Warehouse handelt, in dem keine Veränderungen an den Daten durchgeführt werden (somit keine Inkonsistenzen entstehen können) und vor allem die Performance beim Laden (Updaten) der Daten hoch sein soll. So kann einfach alles aus verschiedenen Quelldaten reinkopiert werden, ohne jedes Mal die Verteilung auf die normalisierten Tabellen vornehmen zu müssen.

Also nochmals vielen Dank für die Unterstützung. So SQL kann schon verdammt komplex werden :)

Phil
 
So kann einfach alles aus verschiedenen Quelldaten reinkopiert werden, ohne jedes Mal die Verteilung auf die normalisierten Tabellen vornehmen zu müssen.
Mit einem Importer, der für die zu erwartenden unterschiedlichen Input-Formate Mdoule benutzt, macht man die Verteilung _genau einmal_ - nämlich beim Schreiben des Importer-Moduls.

Im Übrigen ist Normalisierung nicht nur zur Vermeidung von Inkonsistenzen gut. Ich wette, die Performance deiner Abfrage mit 2 Subselects ist um Größenordnungen schlechter als eine Abfrage auf einer korrekt normalisierten Datenbank.
 
@elias5000:
Das hab ich mir auch überlegt und bin (war) mir nicht sicher, was wirklich besser wäre. Aber in der Literatur wird oft davon gesprochen, dass die DB in einem Data Warehouse nicht (unbedingt) normalisiert werden soll. Zitat von Tecchannel -> Core Dataware Warehouse ? Datenmodelle und Normalisierung | BI-Datenmanagement (Teil 2): Das Data Warehouse :

Normalerweise strebt man bei relationalen Datenbanken die volle Normalisierung an, also die dritte Codd’sche Normalform (vgl. den Artikel Datenmodelle). Nur so lassen sich Redundanzen und Anomalien vermeiden. Im BI-Kontext werden die Normalitätsstufen aber oft rückgängig gemacht oder gar nicht erst ausgeführt, was als „Denormalisierung“ bezeichnet wird.

Dies hat vor allem praktische Gründe. Mit abnehmender Normalisierung lassen sich nämlich auch die Datenbankzugriffe reduzieren, was zur Entlastung der Hardware und Software führt und das Antwortzeitverhalten verbessert. In Kauf genommen wird dabei ein Anstieg des Speicherplatzbedarf der denormalisierten Daten – Folge der redundanten Daten – sowie ein höherer Aufwand zur Erhaltung der Datenkonsistenz.

Aber ich würde nicht sagen dass die Aussage von dir grundsätzlich falsch ist. Kommt es vielleicht auch auf die Daten selbst und die Abfragen an?
 
Last edited by a moderator:
Wir benutzen in einigen unserer Datenbanken (sehr große Anzahl (mehrere Millionen) relationaler Datensätze mit mehreren 1:n und n:m-Verknüfpungen) denormalisierte Tabellen für Abfragen, deren Inhalt per Trigger auf die relationalen Datenbanken aktuell gehalten wird.

Dies verknüpft eine saubere Datenhaltung in einer normalisierten Form mit der auf den speziellen Anwendungsfall voraufbereiteten denormalisierten Version. Natürlich auf Kosten des Speicherplatzes (der heutzutage immer preiswerter wird).

AFAIK ist das das Konzept unter der Gattungsbezeichnung "materialized View" auch in diversen Datenbanken als natives Feature integriert.
 
Na dann sind wir uns ja einig! ;-)
Somit habt ihr genau aus Performance-Gründen eben auch denormalisierte Tabellen. Genau so in meinem Fall, wo zwar die Datenmenge um einiges kleiner ist (zehntausende Datensätze), aber es sich ebenfalls quasi um eine materialisierte Extraktion aus diversen operativen DBs handelt. Und da die Daten nur in den operativen (und normalisierten) Daten bearbeitet werden (und dann regelmässig per Importer wieder ins DWH geschrieben werden), sehe ich einfach nicht ein, warum ich denn die Daten im Data Warehouse denormalisieren soll...
 
Back
Top