PDA

View Full Version : SELECT auf SQL-View funktioniert (nicht)



Akku
08-09-05, 13:53
Hallo,

habe folgende View erstellt:

CREATE VIEW #VTEST AS
SELECT A.HSEBUJH, A.HSESKTO, SUM(A.HSEBETR) AS SUMSKTO,
DEC( SUM(A.HSEBETR) - (
SELECT SUM(HSEBETR) FROM HSEM1 B
WHERE B.HSEBUJH = A.HSEBUJH AND
B.HSEHKTO = A.HSESKTO
), 12, 2) AS SALDO
FROM HSEM1 A
GROUP BY A.HSEBUJH, A.HSESKTO

Sicht #VNTEST in TEST erstellt.

Funktioniert sowohl unter V5R3 als auch unter V5R2 problemlos.

Das Anzeigen der Daten via SELECT * FROM #VTEST funktioniert unter V5R3 ebenfalls problemlos. Unter V5R2 bekomme ich statt einer Anzeige allerdings folgenden Fehler: SQL0112=Argument der Funktion *N enthält eine andere Funktion.

Ist diese Funktionalität tatsächlich erst ab V5R3 möglich? Oder kann dieser Fehler unter V5R2 eventuell mittels Einspielen eines PTFs behoben werden?

Vielen Dank schon einmal im voraus für eure Hilfe.

Viele Grüße
Akku

Fuerchau
08-09-05, 15:04
Es gibt immer wieder Erweiterungen in der DB.
Ab V5R3 ist eben mehr möglich als vorher.
Mach aus dem scalaren Subselect einen Join !

Akku
09-09-05, 09:30
Guten Morgen Hr. Fuerchau,

erstmal vielen Dank für die Antwort. Leider bin ich zu doof, das Subselect durch einen Join zu ersetzen.

Vielleicht erkläre ich einfach mal, was vorhanden ist und was ich brauche:

Die Datei HSEM1 hat folgenden Aufbau:
BUJH, SKTO, HKTO (beides Kontonummern) und ein Betragsfeld (BETR) ... (und noch einen Haufen irrelevanter Felder).

Ich brauche:
BUJH, KTO, Saldo aus (alle Sollbeträge - alle Habenbeträge) für das jeweilige KTO

Ein paar Beispielsätze für Konto 1:
BUJH SKTO HKTO BETR
2004 1 2 10
2004 1 3 20
2004 1 14 30
2004 1 2 40
2004 1 31 50
2004 74 1 60
2004 14 1 70
2004 81 1 80
Saldo für 2004 -60

Hab's über UNION ALL versucht (s.u.) aber hier hat der GROUP BY nicht funktioniert.

create view #Vtest2 as
select hsebujh as bujh, hseskto as kto,
sum(dec(hseewsu, 10, 2)) as sbetr, sum(dec(0, 10, 2)) as hbetr
from hsem1 union all
select hsebujh as bujh, hsehkto as kto,
sum(dec(0, 10, 2)) as sbetr, sum(dec(hseewsu, 10, 2)) as hbetr
from hsem1
group by bujh, kto (oder group by hsebujh, kto ...)

Ohne GROUP BY kann halt erst mit dem SELECT auf die VIEW gruppiert, summiert und gerechnet werden (s.u.)!

create view #Vtest3 as
select hsebujh, hseskto as kto,
dec(hseewsu, 10, 2) as sbetr, dec(0, 10, 2) as hbetr
from hsem1 union all
select hsebujh, hsehkto as kto,
dec(0, 10, 2) as sbetr, dec(hseewsu, 10, 2) as hbetr
from hsem1

und dann

SELECT HSEBUJH, KTO, sum(SBETR), sum(HBETR), sum(SBETR) - sum(HBETR)
FROM #vtest3
GROUP BY hsebujh, kto

Tausend Wege führen nach Rom, aber gibt es nicht einen ohne Umweg? Ich hoffe, ich habe Sie jetzt nicht mit dem vielen Text erschlagen?!

Viele Grüße

Akku

Fuerchau
09-09-05, 10:04
Deine Beziehung (Join) gibst du beim Subselect ja eigentlich bereits an:

SELECT A.HSEBUJH, A.HSESKTO, SUM(A.HSEBETR) AS SUMSKTO,
DEC( SUM(A.HSEBETR) - (
SELECT SUM(HSEBETR) FROM HSEM1 B
WHERE B.HSEBUJH = A.HSEBUJH AND
B.HSEHKTO = A.HSESKTO
), 12, 2) AS SALDO
FROM HSEM1 A
GROUP BY A.HSEBUJH, A.HSESKTO

Also brauchst du das nur noch umbauen:

SELECT A.HSEBUJH, A.HSESKTO, SUM(A.HSEBETR) AS SUMSKTO,
DEC( SUM(A.HSEBETR) - SUM(B.HSEBETR)), 12, 2) AS SALDO
FROM HSEM1 A, HSEM1.B
WHERE B.HSEBUJH = A.HSEBUJH AND
B.HSEHKTO = A.HSESKTO
GROUP BY A.HSEBUJH, A.HSESKTO

Wenn ich mir allerdings die Logik ansehe, müsste da eine 0-Summe rauskommen ?!

Akku
09-09-05, 12:05
Dein Join führt ja zu einer „Satzverlängerung“ der „Primärdatei“ (A.HSEM1), indem nochmals der Satz (durch B.HSEM1) hintergehängt wird. D.h. jeder Satz der Datei A wird um jeden Satz der Datei B verlängert (n:n – Verknüpfung!)

Für meine Beispieltabelle kommen in diesem Fall die folgenden Sätze heraus:

A:_BUJH__SKTO_HKTO__BETR_B: BUJH__SKTO__HKTO_BETR

___2004____1_____2___ 10____ 2004____74_____1__60
___2004____1_____2___ 10____ 2004____14_____1__70
___2004____1_____2___ 10____ 2004____81_____1__80
___2004____1_____3___ 20____ 2004____74_____1__60
___2004____1_____3___ 20____ 2004____14_____1__70
___2004____1_____3___ 20____ 2004____81_____1__80
___2004____1____14___ 30____ 2004____74_____1__60
___2004____1____14___ 30____ 2004____14_____1__70
___2004____1____14___ 30____ 2004____81_____1__80
___2004____1_____2___ 40____ 2004____74_____1__60
___2004____1_____2___ 40____ 2004____14_____1__70
___2004____1_____2___ 40____ 2004____81_____1__80
___2004____1____31___ 50____ 2004____74_____1__60
___2004____1____31___ 50____ 2004____14_____1__70
___2004____1____31___ 50____ 2004____81_____1__80


Summen für A.BETR 450 Summe für B.BETR 1050
Macht Saldo -600

Wie Du siehst, ergäben sich falsche Summen!
(Soll-Summen wären eigentlich A.BETR = 150 und B.BETR = 210)

Problem:
Summe 1 (n Sätze mit Feld SKTO = 1)
Summe 2 (n Sätze, ganz andere, mit Feld HKTO = 1)

Beide Summen resultieren zwar aus demselben Feld (BETR), aber eben aus ganz unterschiedlichen Zeilen.

Das Thema ist wirklich furchtbar schwer zu erklären!!!

Fuerchau
09-09-05, 12:31
???
Wenn du den Select anschaust gibt es 2 Beziehungen (inner Join):

WHERE B.HSEBUJH = A.HSEBUJH AND B.HSEHKTO = A.HSESKTO

Es gibt also eine 1:1 Beziehung zwischen Jahr UND Konten, also genauso wie in deinem ursprünglichen Select !
Wenn diese Beziehung nicht ausreicht, musst du zusätzliche Beziehungen herstellen (weitere AND-Bedingung).

Fuerchau
09-09-05, 12:41
Ich muss mich berichtigen, du hast ja Recht !
Da es auf jedem Konto mehrere Buchungen gibt, gibt es diese N:N-Beziehung.

Ab V5 gibt es folgende Möglichkeit:

with
xSoll as ( -- Summe Soll nach Jahr/Konto
SELECT HSEBUJH, HSESKTO, SUM(HSEBETR) AS SUMSKTO
FROM HSEM1
GROUP BY HSEBUJH, HSESKTO
)
,
xHaben as ( -- Summe Haben nach Jahr/Konto
SELECT HSEBUJH, HSEHKTO, SUM(HSEBETR) AS SUMHKTO
FROM HSEM1
GROUP BY HSEBUJH, HSEHKTO
)
select a.*, b.*, SUMHKTO - SUMSKTO from
xsoll a, xhaben b
WHERE B.HSEBUJH = A.HSEBUJH AND
B.HSEHKTO = A.HSESKTO

B.Hauser
09-09-05, 13:56
Hallo,

hier noch ein anderer Vorschlag, vielleicht ist es das was Du suchst:



create view qtemp/Myview1 as
with s as (select hsebujh, hseskto as Kto,
Sum(hseeswu) as Soll, sum(0) as Haben,
Sum(hseeswu) as Saldo
from hsem1
where hseskto <> ' '
Group by hsebujh, hseskto),
h as (select hsebujh, hsehkto as kto,
Sum(0) as Soll, sum(hseeswu) as Haben,
Sum(-hseeswu) as saldo
from hsem1
where hsehkto <> ' '
Group by hsebujh, hsehkto),
t as (Select * from s
Union
Select * from h)
select hsebujh, kto, sum(soll) as soll,
sum(haben) as haben, sum(saldo) as saldo
from t
group by hsebujh, kto


@Fuerchau: Common Table Expressions (CTEs) werden schon seit Release V4R4 unterstützt.

Akku
12-09-05, 10:41
Guten Morgen ihr Beiden,

tut mir leid, dass ich mich jetzt erst zurückmelde! Aber hatte bisher noch keine Zeit.

Mittlerweile habe ich mir Eure Tipps angesehen, ausprobiert und bin hellauf begeistert. Wunderbar!!! Das "WITH" ist genau das, was ich gesucht habe!

Vielen Dank für Eure Geduld und Hilfe!!!

Viele Grüße

Akku