Anmelden

View Full Version : SQL - Gruppenwechsel-Herausforderung (geht das überhaupt??)



mojo
21-05-15, 10:06
Hallo zusammen,

ich bin neu hier, daher vorweg erstmal ein herzliches HALLO in die Runde!

Leider bin ich grade schwer am verzweifeln mit GROUP BY-Funktionen.
Habe schon einiges nachgelesen und zig Versuche gemacht, bekomme meinen Wunsch jedoch nicht gebacken... :-(

Problemstellung:
Ich habe eine Tabelle mit einer über mehrere Spalten aufgeteilten Artikel-Nr. In dieser Tabelle muss ich die über mehrere Mengen-Felder aufgeteilte Menge je Teil-Artikel-Nr. aufsummieren.

Geht das überhaupt?

Ausgangstabelle:

<colgroup><col style="width:88pt" span="9" width="117"> </colgroup><tbody>
ARTNR_TEIL1

ARTNR_TEIL2
ARTNR_TEIL3
ANZ_GROESSE_1
ANZ_GROESSE_2
ANZ_GROESSE_3
ANZ_GROESSE_4
ANZ_GROESSE_5
ANZ_GROESSE_6


1
002
05
0
1
1
2
4
2


1
002
06
1
2
0
0
2
1


1

003
02
0
0
1
0
0
0


1
004
08
0
1
1
0
0
1


1

004
11
1
3
0
0
0
0


2
120
07
1
1
0
0
0
0


2
120
15
2
0
0
0
0
0


3
120
13
0
1
1
1
1
1


3

044
13
1
1
4
1
1
1

</tbody>

Mein gewünschtes Ergebnis sähe für die o.g. Daten so aus:

<colgroup><col style="width:88pt" span="9" width="117"> </colgroup><tbody>
ARTNR_TEIL1

ARTNR_TEIL2
ARTNR_TEIL3
ANZ_GROESSE_1
ANZ_GROESSE_2
ANZ_GROESSE_3
ANZ_GROESSE_4

ANZ_GROESSE_5
ANZ_GROESSE_6


1
002

05
0
1
1
2
4
2


1
002
06
1
2
0
0
2
1


1

002
NULL
1
3
1
2
6
3


1
003
02
0
0
1
0
0
0


1

003
NULL
0
0
1
0
0
0


1
004
08
0
1

1
0
0
1


1
004

11
1
3
0
0
0
0


1

004
NULL
1
4
2
0
0
1


1

NULL
NULL
2
7
4
2
6
4


2
120
07
1
1
0
0
0
0


2
120
15
2
0
0
0
0
0


2
120
13
0
1
1
1
1
1


2

120
NULL
3
2
1
1
1
1


2

NULL
NULL
3
2
1
1

1
1


3
044
13
1
1
4
1
1
1


3

44
NULL
1
1
4
1
1
1


3

NULL
NULL
1
1
4
1
1
1


NULL

NULL
NULL
6
10
9
4
8
6

</tbody>

(-> die gewünschten Summenzeilen habe ich der Lesbarkeit halber farbig markiert.)

Vielen Dank schonmal im Voraus für eure Hilfe!!

Fuerchau
21-05-15, 10:33
Mit Group by bekommst du das nicht hin.
Dies ist eine typische CUBE-Anforderung, bei der über mehrere Gruppenstufen aggregiert wird.
Beispiele findest du in der SQL-Reference (als PDF-Download verfügbar).
Ist leider aber erst ab V6R1 verfügbar.

Robi
21-05-15, 10:35
hallo und Willkommen,

eigendlich doch nur
select teil1, teil2 , sum(gr1), sum(gr2), sum(gr3) from datei group by teil1, teil2

Oder Wie ?

oder als summentabelle
with a as (
select teil1, teil2, 9999 , sum(gr1), sum(gr2), sum(gr3) from datei group by teil1, teil2)
select alle felder from datei union all select alle felder from a order by 1, 2, 3

Robi
@Birgitta
ja gas geht auch mit with rollup oder so.
Aber ich kanns mir immer nicht merken

Robi
21-05-15, 10:37
und die 1. summenstuffe noch dazu:



with a as (
select teil1, teil2, 9999 , sum(gr1), sum(gr2), sum(gr3)
from datei
group by teil1, teil2
),
b as (
select teil1, 9999, 9999 , sum(gr1), sum(gr2), sum(gr3)
from datei
group by teil1
)
select alle felder
from datei union all select alle felder
from a union all select alle felder
from b
order by 1, 2, 3

Pikachu
21-05-15, 10:39
Das müßte mit Query/400 (WRKQRY/RUNQRY) einfach machbar sein oder auch mit QM-Query (STRQM/STRQMQRY). Oder vielleicht auch als SQL mit einzelnen SELECTs je Gruppenwechselstufe, und alle inklusive der Datei selbst verbunden durch UNION ALL.

Fuerchau
21-05-15, 11:09
Mit einfachen SQL's scheitert man ggf. an der Sortierfolge, da spätestens auf der nächst höheren Ebene und am Schluss Gruppenschlüssel NULL sind und die werden nach vorne sortiert.
Um einen Order by kommt man da wohl nicht herum.
Hier das Handbuch-Beispiel:



The following query:

SELECT
SALES_DATE, SALES_PERSON,

SUM
(SALES) AS UNITS_SOLD,

GROUPING
(SALES_DATE) AS DATE_GROUP,

GROUPING
(SALES_PERSON) AS SALES_GROUP

FROM
SALES

GROUP BY CUBE
( SALES_DATE, SALES_PERSON)

ORDER BY
SALES_DATE, SALES_PERSON

Results in:

SALES_DATE SALES_PERSON UNITS_SOLD DATE_GROUP SALES_GROUP

---------- ------------ ---------- ---------- -----------

12/31/1995 GOUNOT 1 0 0

12/31/1995 LEE 6 0 0

12/31/1995 LUCCHESSI 1 0 0

12/31/1995 - 8 0 1

03/29/1996 GOUNOT 11 0 0

03/29/1996 LEE 12 0 0

03/29/1996 LUCCHESSI 4 0 0

03/29/1996 - 27 0 1

03/30/1996 GOUNOT 21 0 0

03/30/1996 LEE 21 0 0

03/30/1996 LUCCHESSI 4 0 0

03/30/1996 - 46 0 1

03/31/1996 GOUNOT 3 0 0

03/31/1996 LEE 27 0 0

03/31/1996 LUCCHESSI 1 0 0

03/31/1996 - 31 0 1

04/01/1996 GOUNOT 14 0 0

04/01/1996 LEE 25 0 0

04/01/1996 LUCCHESSI 4 0 0

04/01/1996 - 43 0 1

- GOUNOT 50 1 0

mojo
21-05-15, 13:13
Hallo zusammen und vielen Dank für die vielen Antworten!

ich habe ich zwischenzeitlich noch weiter mit dem Thema auseinander gesetzt und meine Lösung in den GROUPING SETS gefunden.

Hier die Lösung umgesetzt auf meine o.g. Beispiel-Situation:


select ARTNR_TEIL1, ARTNR_TEIL2, ARTNR_TEIL3,
sum(ANZ_GROESSE_1), sum(ANZ_GROESSE_2), sum(ANZ_GROESSE_3),
sum(ANZ_GROESSE_4), sum(ANZ_GROESSE_5), sum(ANZ_GROESSE_6)
FROM tabelle
Group by Grouping Sets((ARTNR_TEIL1, ARTNR_TEIL2, ARTNR_TEIL3),
(ARTNR_TEIL1, ARTNR_TEIL2)
(ARTNR_TEIL1)
() );


Besten Dank allerseits! :cool:

ExAzubi
21-05-15, 13:18
Ich würde es mal mit ROLLUP probieren...

SELECT CASE WHEN (GROUPING(ARTNR_TEIL1) = 1) THEN 'Summe ART 1'
ELSE ISNULL(ARTNR_TEIL1, 'UNKNOWN')
END AS Art1,
CASE WHEN (GROUPING(ARTNR_TEIL2) = 1) THEN 'Summe ART 2'
ELSE ISNULL(ARTNR_TEIL2, 'UNKNOWN')
END AS Art2,
CASE WHEN (GROUPING(ARTNR_TEIL3) = 1) THEN 'Summe ART 3'
ELSE ISNULL(ARTNR_TEIL3, 'UNKNOWN')
END AS Art3,
SUM(ANZ_GROESSE_1) AS Sum1,
SUM(ANZ_GROESSE_2) AS Sum2,
SUM(ANZ_GROESSE_3) AS Sum3,
FROM TABLE
GROUP BY ARTNR_TEIL1, ARTNR_TEIL2, ARTNR_TEIL3 WITH ROLLUP

Fuerchau
21-05-15, 15:35
Group by Cube scheint mir das selbe Ergebnis zu bringen.

B.Hauser
22-05-15, 07:51
Das ist kein CUBE, da dieser alle möglichen Summen-Kombinationen bildet, sondern ein ROLLUP.
Mit Grouping Set geht das natürlich auch, ist aber etwas komplizierter.


Select ArtNr_Teil1, ArtNr_Teil2, ArtNr_Teil3,
sum(Anz_Groesse1),
sum(Anz_Groesse2),
sum(Anz_Groesse3),
sum(Anz_Groesse4),
sum(Anz_Groesse5),
sum(Anz_Groesse6)
From ArtTable
Group By Rollup(ArtNr_Teil1, ArtNr_Teil2, ArtNr_Teil3)
Order By ArtNr_Teil1, ArtNr_Teil2, ArtNr_Teil3;

Birgitta

Geht allerdings erst seit Release 6.1

Birgitta