PDA

View Full Version : SQL Select * ... group by



Seiten : [1] 2

DISCOME
28-04-11, 07:05
Hallo zusammen,

ich habe da mal wieder ein kleines Problemchen.´und ich hoffe man kann mir helfen.

Ich habe eine SQL Abfrage



SELECT *
FROM BPCSF.ITHL01
LEFT JOIN BPCSF.IIML01
ON TPROD = IPROD
LEFT JOIN BPCSF.AVML01
ON TPROD = VENDOR

Where TTDTE >= 20110331 and IITYP ='K'

Group BY TPROD


Nur das mit dem "Group by" geht nicht. Ich arbeite mit PHP als Ausgabe und ziehe mir die Daten gezielt raus, daher das Select *.

Robi
28-04-11, 07:45
Moin
bei diesem angenommenen Dateiaufbau

2011.03.31 Produkt1
2011.04.07 Produkt1
2011.04.15 Produkt1
2011.05.14 GanzAnderesProdukt
...

Was erwartest du denn beim group by im Datum ?

also ... geht nicht

Gruß
Robi

DISCOME
28-04-11, 08:05
Also wenn mein SQL spuckt ca. 4000 Datensätze a 60 Spalten aus. Und per PHP ziehe ich sie raus. Ich kann doch nicht 60 Spalten ins Select tippen... nur weil ich eine Spalte ins Group nehme...:o

Pikachu
28-04-11, 08:17
Wenn ich jetzt nicht ganz daneben liege, erhältst du bei einer Spalte im GROUP BY maximal 1 Zeile je Wert in dieser Spalte. Welche Werte aus den anderen Spalten willst du haben, wenn es da unterschiedliche gibt, wie im Beispiel von Robi?

Fuerchau
28-04-11, 08:47
Das Hauptproblem ist bei Group By, dass du Aggregatfunktionen für die Felder benötigst, die nicht im Group by aufgelistet werden.
Infolge dessen kannst du keinen "select * " verwenden.
Du musst SQL schon genau mitteilen, was du willst:

select F1 [, F2, ...], SUM(Fn) as Fn [AVG(Fn1), ...]
from MyFile
Group By F1 [, F2, ...]

DISCOME
28-04-11, 10:58
Habe nun ein paar Select eingetragen... zum testen und es klappt leider nicht..



SELECT TPROD, *von ITHL01
TTDTE, *von ITHL01
IPROD, *von IIML01
IDESC, *von IIML01
VENDOR *von AVML01
FROM BPCSF.ITHL01

LEFT JOIN BPCSF.IIML01
ON TPROD = IPROD

LEFT JOIN BPCSF.AVML01
ON IPROD = VENDOR
Where TTDTE >= 20110331
and IITYP ='K'


Da ist der Wurm drin.

Fehlercode

SQL-Status: 42703
Vendorencode: -5001
Nachricht: [SQL5001] Qualifikationsmerkmal für Spalte oder Tabelle ITHL01 nicht definiert. Ursache . . . . : Der Name ITHL01 wurde zur Qualifizierung eines Spaltennamens verwendet oder als Operand der Skalarfunktion RRN, HASHED_VALUE, PARTITION, NODENAME, NODENUMBER, DBPARTITIONNAME, DBPARTITIONNUM, DATAPARTITIONNAME oder DATAPARTITIONNUM angegeben. Der Name ist in dieser SQL-Anweisung nicht als Tabellenbezeichnung definiert oder die Tabellenbezeichnung kann dort, wo sie in der SQL-Anweisung angegeben ist, nicht referenziert werden. Wird in einer Klausel FROM hinter dem Tabellennamen ein Korrelationsname angegeben, wird dieser als Tabellenbezeichnung interpretiert. Wird kein Korrelationsname angegeben, wird der Tabellenname als Tabellenbezeichnung interpretiert. Wird die SQL-Benennung verwendet und ist die Tabelle durch einen Berechtigungsnamen qualifiziert, lautet die Tabellenbezeichnung Berechtigungsname.Tabellenname. Ist kein Berechtigungsname angegeben, ist die Tabellenbezeichnung der implizite Berechtigungsname, gefolgt vom Tabellennamen. Korrelation von einem verschachtelten Tabellenausdruck zu einer übergeordneten Tabelle ist nur zulässig, wenn das Schlüsselwort TABLE für die Definition des verschachtelten Tabellenausdrucks verwendet wird. Ist der Name *N, ist ein lateraler Korrelationsverweis aus einem verschachtelten Tabellenausdruck nicht zulässig. Aus einem der folgenden Gründe kann keine Korrelationsbeziehung zu einer Tabelle hergestellt werden, die dem verschachtelten Tabellenausdruck übergeordnet ist: -- Der verschachtelte Tabellenausdruck enthält UNION, EXCEPT oder INTERSECT. -- Der verschachtelte Tabellenausdruck enthält das Schlüsselwort DISTINCT in der Klausel SELECT. -- Der verschachtelte Tabellenausdruck enthält eine Klausel ORDER BY. -- Der Korrelationsbezug befindet sich in derselben Klausel FROM wie der verschachtelte Tabellenausdruck, ist aber Teil eines RIGHT OUTER JOIN oder RIGHT EXCEPTION JOIN. -- Der verschachtelte Tabellenausdruck befindet sich in der Klausel FROM eines anderen verschachtelten Tabellenausdrucks, der eine dieser Einschränkungen enthält. In einer OLAP-Funktion muss die Tabellenbezeichnung ORDER OF auf eine Tabellenbezeichnung in der Klausel FROM der Unterauswahl verweisen. Fehlerbeseitigung: Sicherstellen, dass alle Spaltennamen durch eine gültige Tabellenbezeichnung qualifiziert sind. Sicherstellen, dass eine Tabellenbezeichnung als Argument für die Funktion angegeben ist. Das Schlüsselwort TABLE verwenden, damit korrelierte Spalten innerhalb eines verschachtelten Tabellenausdrucks zulässig sind. Die Anforderung wiederholen.
Verarbeitung wurde beendet, da die hervorgehobene Anweisung nicht erfolgreich abgeschlossen werden konnte

Fuerchau
28-04-11, 11:19
Nun ja, ohne die Fehlermeldung können wir hier nichts machen.
Lass dir mal die Fehlermeldung ausgeben, damit sieht man dann klarer.

Alternativ kannst du je erst mal auf der AS/400 per STRSQL die Selects probieren (Mit F13 Auswahl 1 am Besten auf *SQL-Naming umschalten, dann bleibt die Syntax identisch).

Oder mit dem Operationsnavigator die SQL's ausprobieren.

B.Hauser
28-04-11, 11:29
Um was geht es eigentlich?
Willst Du die Sätze aufsummieren oder willst Du nur, dass keine Duplikate angezeigt werden?

In Deinem letzten Beispiel hast Du zwar mehrere Felder aus unterschiedlichen Dateien ausgewählt, aber ich sehe weder eine Aggregat-Funktion (z.B. Sum(Fldx) oder Count(*) ) noch einen Group By.

Beim Left Outer Join muss man außerdem berücksichtigen, dass sofern in der zweiten Datei kein Pendant gefunden wird NULL-Werte ausgegeben werden.
Bei NULL-Werten ist zu beachten, dass sie außerhalb des gültigen Bereichs sind und deshalb entweder separat abgefragt oder in Default-Werte konvertiert werden müssen. Außerdem werden NULL-Werte in Aggregat-Funktionen nicht berücksichtigt. Das mag beim SUM() egal sein, jedoch bei COUNT() oder AVG() werden andere Ergebnisse ausgegeben.

Wenn Du lediglich Duplikate vermeiden und keine Aggregat-Funktionen verwenden willst, kannst Du auch wie folgt vorgehen (Group By ist in diesem Fall nicht erforderlich):


Select Distinct File1.*, File2,*, File3,*
From File1 left Join File2 on ...
left Join File3 on ...
Where ....;

Birgitta

DISCOME
28-04-11, 11:44
Ich danke euch erst mal für eure Unterstützung.

Also in der ITHL01 sind Auftragsdaten des Tages seit 2007 vorhanden. Mit Teilenummern TPROD (mehrfach verarbeitet am Tag) und diese Nummer sind als IPROD in der IIML01 abgespeichert. Nun muss nur noch IPROD mit VENDOR aus der AVML01 abgeglichen werden... Und aus allen Tabellen müssen Div. Daten gezogen werden. Ca 30 Werte.... daher mein erster Gedanke mit dem * nach SELECT

Fuerchau
28-04-11, 11:47
Im ersten Ansatz würde ich vermuten, dass es doppelte Feldnamen aus verschiedenen Tabellen gibt.
SQL muss da schon wissen welches Feld du da meinst, außerdem müssen Kommentare mit
/* Kommentar */
oder
-- Kommentar < CR > < LF >
eingebettet sein:

SELECT A.TPROD, /*von ITHL01 */
A.TTDTE, /*von ITHL01 */
B.IPROD, /*von IIML01 */
B.IDESC, /*von IIML01 */
C.VENDOR /*von AVML01 */
FROM BPCSF.ITHL01 A

LEFT JOIN BPCSF.IIML01 B
ON A.TPROD = B.IPROD

LEFT JOIN BPCSF.AVML01 C
ON B.IPROD = C.VENDOR
Where A.TTDTE >= 20110331
and B.IITYP ='K'