PDA

View Full Version : Query distinct



Seiten : [1] 2

KingofKning
21-10-09, 12:03
Hallo *all,

ich mach ein Abfrage in meinem ERP-System und eine der 4 Dateien ist die Lagerdatei, dummerweise haben wir 2 Läger, ich möchte aber in meiner Auswertung des Artikel nur jeweils das erste Lager mit Bestand angezeigt bekommen.

Ein Distinct wie in SQL gibt es ja nicht. Könnte ich mir eine View anlegen in der nur jeweils der Erste Satz drin steht oder welche Möglichkeit habe ich?

Schlußendlich will ich aus der ganzen Query eine View machen damit ich die Daten einem Fremdprogramm übergeben kann.

Anfang auf Zeile . . . . . . An
Zeile ....+....1....+....2....+....3....+....4....+....5 ....+....6....+....7....+....8....+...
STS FA LGNR TENR MBST MEPU LFBS WTPU
Status Firma Lag. TeileNr. Mindest Menge/ laufender BestandWert
0=Akt. /Werk Nr. Bestand Ultimo Bestand /Ultimo
000001 1 3 237526 25000,00 24717,00 79166,00 9145,04
000002 1 1 237526 480,00 13920,00- 177,60
****** ******** Ende des Berichts ********

Fuerchau
21-10-09, 12:51
Dann machst du am Besten einen QM-Query daraus. Per STRQMQRY kannst du dann eine Ausgabedatei angeben. Query brauchst du da dann nicht mehr.

KingofKning
21-10-09, 13:06
Hallo,

ich möchte keine Ausgabedatei erzeugen, sondern eine View damit die Fremdsoftware (Aruba) sich per SQL die Daten holen kann die sie für die Auswertung braucht.

GG

B.Hauser
21-10-09, 13:33
Irgendwie bin ich verwirrt.
1. Du verwendest Query/400 aber da gibt es kein DISTINCT
2. Du willst aus dem Query/400 eine View machen? Wieso?
3. Diese View willst Du dann weiterverarbeiten.

Warum nicht eine SQL-View generieren (hier kann man auch DISTINCT verwenden) und diese View dann im Query/400 einsetzen.

Wenn Du außerdem nur die Daten des einen Lagers willst, warm schließt Du das zweite nicht einfach aus, bzw. forderst explizit nur die Daten des ersten Lagers (Sätze auswählen) an?

Birgitta

UFK
21-10-09, 15:33
ich mach ein Abfrage in meinem ERP-System und eine der 4 Dateien ist die Lagerdatei, dummerweise haben wir 2 Läger, ich möchte aber in meiner Auswertung des Artikel nur jeweils das erste Lager mit Bestand angezeigt bekommen.


Ich denke, Du meinst das erste Lager, das Bestand hat. Ist es dabei wichtig, wie groß dieser Bestand ist, und kann es sein, daß evtl. doch beide Lager herhalten müssen, wenn keines für sich genug Bestand hat ?


Könnte ich mir eine View anlegen in der nur jeweils der Erste Satz drin steht oder welche Möglichkeit habe ich?

Ich denke da eher ein eine Stored-Procedure oder UserDefinedFunction, die dynamisch als Ergebnis genau diese Tabelle liefert.

Wenn Du die Menge nicht variabel abfragen mußt, sondern z.B. nur einen Mindestbestand abfragst, der selber auch gespeichert ist, (oder einfach "gibt es überhaupt irgendeinen Bestand > 0 ?"), würde ich zwei Unterabfragen formulieren, und sie in der Hautptabfrage miteinander korrelieren. Also

A: gibt es Bestand in Lager A und
B: gibt es Bestand in Lager B, wenn der A.Bestand 0 oder zu klein ist, ...

So eine Korrelation kann auch als View angelegt werden, läuft aber immer etwas langsamer als ein simples SELECT. Sie ist gut für Einzelabfragen (Ordermenge x zu Auftrag a und Produkt p), aber für Massenabfragen evtl. etwas langsam.

Das schnellste ist natürlich ein UNION (der evtl. 2 Zeilen liefert) oder ein JOIN, soweit es eine genau bekannte Anzahl von Lagern gibt. In dem JOIN könnest Du z.B. den größten Bestand und die betreffende Lagernummer nennen.

Wege gibts also sehr viele. Man bräuchte mehr Infos über Deine Aufgabenstellung ...

KingofKning
21-10-09, 16:17
Irgendwie bin ich verwirrt.
1. Du verwendest Query/400 aber da gibt es kein DISTINCT
2. Du willst aus dem Query/400 eine View machen? Wieso?
3. Diese View willst Du dann weiterverarbeiten.

Warum nicht eine SQL-View generieren (hier kann man auch DISTINCT verwenden) und diese View dann im Query/400 einsetzen.

Wenn Du außerdem nur die Daten des einen Lagers willst, warm schließt Du das zweite nicht einfach aus, bzw. forderst explizit nur die Daten des ersten Lagers (Sätze auswählen) an?

Birgitta

Hallo Birgitta, da ich in SQL nicht ganz so fit bin, erarbeite ich mir das Ziel mit Query, da ich dort für meine Verhältnisse schnell die benötigten Felder aus den 4 Dateien auswählen kann und schauen kann ob das Ergebnis in der Summe so ist wie die Kollegen es schlußendlich brauchen. Das Problem mit dem Lager ist, das eigentlich ein Artikel nur in einem Lager auftauchen sollte. Leider wird bei uns mal in dem einem Standort dann mal in dem anderen Standort der Artikel produziert und gelagert deswegen weiß ich auch nicht in welchem Lager der Artikel ist bzw. ob evtl noch Restmengen in dem anderen Lager sind. Prinzipiell brauche ich nicht die Unterscheidung in Läger sondern nur die gesamt Summe. Da ich ja schon recht weit gekommen bin, werde ich mal die Query in eine SQL-View überführen. GG

KingofKning
21-10-09, 16:24
Ich denke, Du meinst das erste Lager, das Bestand hat. Ist es dabei wichtig, wie groß dieser Bestand ist, und kann es sein, daß evtl. doch beide Lager herhalten müssen, wenn keines für sich genug Bestand hat ?


Ich denke da eher ein eine Stored-Procedure oder UserDefinedFunction, die dynamisch als Ergebnis genau diese Tabelle liefert.

Wenn Du die Menge nicht variabel abfragen mußt, sondern z.B. nur einen Mindestbestand abfragst, der selber auch gespeichert ist, (oder einfach "gibt es überhaupt irgendeinen Bestand > 0 ?"), würde ich zwei Unterabfragen formulieren, und sie in der Hautptabfrage miteinander korrelieren. Also

A: gibt es Bestand in Lager A und
B: gibt es Bestand in Lager B, wenn der A.Bestand 0 oder zu klein ist, ...

So eine Korrelation kann auch als View angelegt werden, läuft aber immer etwas langsamer als ein simples SELECT. Sie ist gut für Einzelabfragen (Ordermenge x zu Auftrag a und Produkt p), aber für Massenabfragen evtl. etwas langsam.

Das schnellste ist natürlich ein UNION (der evtl. 2 Zeilen liefert) oder ein JOIN, soweit es eine genau bekannte Anzahl von Lagern gibt. In dem JOIN könnest Du z.B. den größten Bestand und die betreffende Lagernummer nennen.

Wege gibts also sehr viele. Man bräuchte mehr Infos über Deine Aufgabenstellung ...

Also mit stored -procedure etc. habe ich mich noch nie beschäftigt. Der Union ist genau das was ich nicht brauche, weil ich dann 2 Zeilen habe, ich benötige schon den join der mir z.B. die größte Menge zurück gibt. Vielleicht kannst Du mir ja sagen wie der Join aussehn muß wenn die Felder z.B. Firma/Lager/Artikel/Menge wären und ich halt den einen! Satz mit der größeren Menge habe will. Das Problem bei 2 Sätzen ist halt das dann alle Felder 2 mal da sind, sprich auch die aus den anderen Dateien. GG

UFK
21-10-09, 16:48
Ja. mache ich heute abend, muß aber erst noch was besorgen ...

B.Hauser
21-10-09, 21:10
Wenn ich das richtig verstanden habe müsste ein Statement, das etwa wie folgt aussieht funktionieren:


Select Fld1, Fld2, Fld3, ... FldN
From Table1 inner join Table2 on Key1Table1 = Key1Table2 and Key2Table1 = Key2Table2 ...
inner join Table3 on KeyATable1 = KeyATable3 and KeyBTable1 = KeyBTable3 ...
inner join Table4 on KeyXTable3 = KeyXTable4 and KeyYTable3 = KeyYTable4 ...
Where ...

Gesetzt der Fall, dass Du in der Auswertung nur den gesamten Artikel-Bestand (unabhängig vom Lager) brauchst und das Lager auch in der SELECT-Liste nicht angegeben wird, könnte die Abfrage etwa wie folgt aussehen:


Select Fld1, Fld2, Fld3, ArtNr, Sum(ArtBest) as ArtBest
From Table1 inner join Table2 on Key1Table1 = Key1Table2 and Key2Table1 = Key2Table2 ...
inner join Table3 on KeyATable1 = KeyATable3 and KeyBTable1 = KeyBTable3 ...
inner join Table4 on KeyXTable3 = KeyXTable4 and KeyYTable3 = KeyYTable4 ...
Where ...
Group By Fld1, Fld2, Fld3, ArtNr

Sollte diese Abfrage zum richtigen Ergebnis führen, brauchst Du daraus nur noch eine View zu machen:


Create View MyLib/MyView
as (Select .... )

Wenn Du allerdings ein Lager mit angeben musst und die Gesamtartikelmenge dazu anzeigen musst ist das zum einen Pfusch und zum anderen müsste man dann noch ein bisschen mehr tricksen.

Birgitta

UFK
22-10-09, 04:15
Was Britta geschrieben hat, geht nur dann gut, wenn in beiden Lagern jeweils alle Artikelnummern geführt werden, und keine fehlen, meine ich. In einem Join würde ich besonders mit CASE WHEN ... die betreffenden Felder auswählen ..

Ich denke aber eher an UNION, SUBSELECTS und KORRELATIONEN:


Select A.Firma, A.Lager, A.Artikel, A.Menge from fileA A where A.Menge>0

Union

Select B.Firma, B.Lager, B.Artikel, B.Menge from fileB B where B.Menge>0
and B.Artikel not in
( select X.Artikel from fileA X
where X.Artikel=B.Artikel and X.Menge>0 )

---

Den Ausdruck X.Artikel=B.Artikel in der letzten Zeile nenne ich hierbei „Korrelation“.

Hier wird natürlich das Lager aus FileA ganz stark priorisiert, Du kannst das obere SELECT aber auch mit Korrelation auf das untere formulieren, und beispielsweise abfragen, welcher Bestand jeweils größer ist, um den größeren dann auszuwerten, und den kleineren zu ignorieren … Dann wäre kein Lager priorisiert..

In Deinem Fall könnte ich mir auch vorstellen, daß es vielleicht in jedem Lager Mindestbestände gibt,
verfügbare Bestände, Bestellbestände, per ultimo fortgeschriebene Bestände usw. Evtl. mußt Du die SELECTs so formulieren, daß sie die BestandsMengen oder die BedarfsMengen kumulieren, oder irgendwie berücksichtigen. Du solltest die Anforderung mal ganz genau (umgangssprachlich) formulieren. Man kann dann viel besser sehen, ob das deklarativ (in SQL) ausgedrückt werden kann, oder ob man es prozedural (mit STORED PROCEDURES und USER DEFINED FUNCTIONS) angehen sollte.

PS: das SELECT mit UNION mußt Du evtl. noch um Klammern und Bezeichner erweitern, es sollte aber funktionieren.
Ich kann noch nicht versprechen, daß Du dies als View speichern kannst, oder als MATERIALIZED VIEW ... Die Ausgabe eher.
Wenns überhaupt nicht geht, würde ich eine UserDefinedFunction draus machen, vielleicht etwas modularer als UDTF
mit einem Input-Parameter ARTIKELNR, und einem Datensatz als Result, das läßt sich dann schön leicht wiederverwenden,
d.h. genau so, wie jede andere Funktion im SQL auch. Die Funktion (UDTF) müßte man aber regelrecht programmieren ...