PDA

View Full Version : Sql will nicht so wie ich



Seiten : [1] 2

Spezlerin
15-06-10, 09:55
Ich habe eín kleines Programm in Vb entwickelt in dem ich über Sql Abfragen auf die AS 400 Tabellen zugriff habe. Nun habe ich 3 Tabellen, aus denen ich Sendungsnummern, Preise und Nebenkosten selektieren möchte.
Select A.ARSN, Sum(B.ARFB + B.ARMB + B.ARRBEM ) as Preis, Sum(C.ARNBS) as Nebenkosten
From From TM.AUHD0P as A Join TM.AUS2BP as B on A.ARSN = B.ARSN Left JOIN TM.AUS3NP as C on a.ARSN = C.ARSN
where A.ARDTEF BETWEEN " & datvon & " and " & datbis & " and A.ARNL = 88 and b.ARNL = 88 and A.ARTARN IN '" & art & "'
And (NOT(C.ARNBS = 199))And B.ARTEIL IN ( 'K',' ' ) And C.ARTEIL IN ( 'K',' ')
Wenn nun aber manche Datensätze keine Nebenkosten besitzen (C....) gibt es diesen Datensatz in der Tab C nicht und der gesamte Datensatz wird nicht angzeigt.
Ich möchte aber die Kosten auch für die Sätze haben in denen keine Nebenkosten enthalten sind.
Wie kann ich das umsetzen? Weiss jemand Rat?

andreaspr@aon.at
15-06-10, 09:59
Hi,
mit OUTER JOIN geht das.

Pikachu
15-06-10, 10:07
Die Bedingungen für B und C dürfen nicht in WHERE-Klausel, sondern müssen in die ON-Klauseln. Und dann brauchst du vermutlich teilweise noch VALUE() oder COALESCE() für die Spalten aus B und C, da auch NULL-Werte anstelle von numerischen Werten kommen können.

B.Hauser
15-06-10, 10:33
Ein LEFT OUTER-Join ist vorhanden und die Verknüpfung sieht auch ordentlich aus, aber...

In der Where-Bedingung werden nur Datenstätze berücksichtigt, mit C.ARTEIL IN ('K', ' '). Wenn jetzt kein Datensatz für die Nebenkosten gefunden wird, ist C.ARTEIL = NULL und wird damit nicht selektiert.

Bei (NOT(C.ARNBS = 199)) dürfte es keine Probleme geben, da nur Datensätze die nicht 199 sind ausgewählt werden. (Ich würde die Schreibweise: C.ARNBS <> 199 oder C.ARNBS != 199 bevorzugen.

Du musst also Deine Where-Bedingung wie folgt erweitern:


... and (C.ARTEIL ('K', ' ') or C.ARTEIL is NULL)

Fuerchau
15-06-10, 10:37
Select A.ARSN, Sum(B.ARFB + B.ARMB + B.ARRBEM ) as Preis, Sum(C.ARNBS) as Nebenkosten
From
TM.AUHD0P as A
left Join TM.AUS2BP as B on A.ARSN = B.ARSN
Left JOIN TM.AUS3NP as C on a.ARSN = C.ARSN
where A.ARDTEF BETWEEN " & datvon & " and " & datbis & " and A.ARNL = 88 and (b.ARNL = 88 or b.ARNL is null) and A.ARTARN IN '" & art & "'
And ((NOT(C.ARNBS = 199) or c.arnbs is null))And (B.ARTEIL IN ( 'K',' ' ) or b.ARTEIL is null) And (C.ARTEIL IN ( 'K',' ') or c.ARTEIL is null)

Das Problem ist generell, dass Where-bedingungen auf Left-Join-Felder automatisch einen Inner-Join daraus machen.

Spezlerin
15-06-10, 13:59
Klasse! So weit so gut.
Aber was ist wenn jetzt
C.ARTEIL IN ('K') = True aber
in diesem Datensatz auch
C.ARNBS = 199
Dann ist weder C.ARTEIL noch
C.ARNBS is null.
aber durch
NOT (C.ARNBS = 199
wird dieser Datensatz vernachlässigt.

Denk ich zu kompliziert!?

Pikachu
15-06-10, 14:22
Probier doch mal das And (NOT(C.ARNBS = 199)) und das And C.ARTEIL IN ( 'K',' ') direkt hinter das on a.ARSN = C.ARSN zu setzen.

Spezlerin
16-06-10, 10:02
Habe das Problem, daß die Datensätze
die in Tabelle C in ARTEIL = U haben, durch "C.ARTEIL IN ('K')" in "WHERE"
nicht angezeigt werden.
Aber sie sind auch nicht null also trifft "c.ARTEIL is null" auch nicht zu. 'Wie kann ich diese Datensätze die Umsätze in TAB A und B haben anzeigen.
Die Abfrage müsste also trotz das in C nicht Verwertbares gefunden wird Einträge aus TAB A und B anzeigen.

Pikachu
16-06-10, 10:24
Schon mal so probiert?

Probier doch mal das And (NOT(C.ARNBS = 199)) und das And C.ARTEIL IN ( 'K',' ') direkt hinter das on a.ARSN = C.ARSN zu setzen.

Fuerchau
16-06-10, 13:41
Nun, wenn du Daten aus 2 Tabellen und/oder haben möchtest, geht das eigentlich nicht per Join.
Beim Join hast du eine Primary und Secondaries, was du in der Primary nicht hast kannst du also in der Secondary auch nicht finden.

Dies ist ein klassischer Fall von UNION:

select f1, f2, f3, ... from TabA
[left] join ...
where ...
union [ALL]
select f1, f2, f3, ... from TabB
[left] join ...
where ...
order by ...

Wichtig ist ggf. "union all", da ansonsten identische Sätze wie bei "select distinct ..." ausgefiltert werden.