PDA

View Full Version : SQL Tabelle



ILEMax
02-09-20, 14:16
Moinsen,

ich habe 2 Tabellen,

TB_A mit A1, A2, A3 ...., P1 (ca 8 mio Sätze, keind der benötigten Felder ist unique)

TB_P mit P1, P2 (ca 30 Sätze, P1 ist unique)



Ich brauche nun eine View die TB_A zählt, gruppiert auf A1, A2 und P1

Es sollen aber alle TB_P werte hintereinander stehen


TB_B
P1 P2
100 bla
101 blub
102 buba

TB_A
A1 A2 A3 ... P1
1 1 xyz 100
1 1 abc 100
1 1 xyz 101
1 1 abc 101
1 1 eee 102
1 2 def 100
1 2 fff 100


Ausgabe

A1 A2 Anzahl Anzahl Anzahl
mit 100 mit 101 mit 102 ...
1 1 2 2 1
1 2 2 0 0
...



Wenn ich die Werte aus TB_P kennen würde, könnte ich

select a1, a2, count(*),
coalesce((select count(*) from tb_a x where x.a1=a1 and x.a2=a2 and P1 = 101 group by x.a1, x.a2, x.p1), 0),
coalesce((select count(*) from tb_a x where x.a1=a1 and x.a2=a2 and P1 = 102 group by x.a1, x.a2, x.p1), 0),
...
from TB_A where p1 = 100 group by a1, a2 machen

(oder so ähnlich)

aber ich kenne die Werte nicht, die ändern sich auch immer ...

So hoffe das ist einigermassen verständlich

der ILEMax

B.Hauser
02-09-20, 15:30
Wenn Du eine View basteln willst, benötigst Du eine fixe Spalten-Anzahl. Wenn die Werte (und somit auch die Anzahl der Spalten nicht bekannt ist), wird es schwierig.

Das einzige was Du machen kannst, ist eine feste Anzahl an Spalten vorzusehen und dann die Spalten, abh. von den P1-Werten eine nach der anderen befüllen.
Etwa so:


With x as (Select Row_Number() Over(Order By P1) P1Count, P1 BP1
from TableB)
Select A1, A2, Sum(Case When P1Count = 1 Then 1 Else 0 End) Col1,
Sum(Case When P1Count = 2 Then 1 Else 0 End) Col2,
Sum(Case When P1Count = 3 Then 1 Else 0 End) Col3,
Sum(Case When P1Count = 4 Then 1 Else 0 End) Col4,
.... weitere Spalten
from x join TableA on P1 = BP1
Group By a1, a2;


Birgitta

ILEMax
02-09-20, 16:23
Danke, das hilft schon mal ....

Ich dachte, aufgrund dieses Posts (http://newsolutions.de/forum-systemi-as400-i5-iseries/threads/22232-SQL-Lines-verdoppeln-bzw-abh%C3%A4ngig-von-Menge-verdoppeln) würde es da was tolles geben ....

Fuerchau
02-09-20, 18:39
Nein, das ist nicht vergleichbar, da hier komplette Zeilen vervielfältigt werden. Was du brauchst ist der selective Count:

count(case p1 when 101 then A3 else NULL)

Der Count zählt die Anzahl Sätze, in denen A3 nicht NULL ist.
Birgitta zählt unabhängig vom Inhalt.

count(case p1 when 101 then 1 else NULL)

käme auf das selbe heraus, da ich ja zählen will und keine Summe benötige. Aber das ist Geschmackssache.
Dies ist übrigens eine ähnliche Vorgehensweise wie beim SQL-Server die Pivot-Funktion.

B.Hauser
03-09-20, 06:57
Nein, das ist nicht vergleichbar, da hier komplette Zeilen vervielfältigt werden. Was du brauchst ist der selective Count:

count(case p1 when 101 then A3 else NULL)

Der Count zählt die Anzahl Sätze, in denen A3 nicht NULL ist.
Birgitta zählt unabhängig vom Inhalt.

count(case p1 when 101 then 1 else NULL)

käme auf das selbe heraus, da ich ja zählen will und keine Summe benötige. Aber das ist Geschmackssache.
Dies ist übrigens eine ähnliche Vorgehensweise wie beim SQL-Server die Pivot-Funktion.

Meine Antwort hat genau der Anforderung entsprochen!
Der Casus-Knacksus ist, dass die Werte aufgrund derer die Spalten gebildet werden sollten
a) nicht bekannt sind und sich
b) ändern können.

Deshalb habe ich mit die Row_Number() eine Dummy-Zuweisung gemacht, die Spalten aufgrund der Zuweisung gebildet und den Inhalt entsprechend abgezählt.
Dass es, sofern die Werte bekannt sind bessere Lösungen gibt steht außer Frage.

@Baldur: Wenn Du schon Beispiele zeigst sollte auch die Syntax korrekt sein. In beiden Case-Anweisungen fehlt das END!

Außerdem ist ELSE NULL der Default bei nicht gefunden, d.h. die Angabe ist optional.

Birgitta

Fuerchau
03-09-20, 08:19
@Birgitta
Da bin ich anderer Meinung (Syntaxfehler außer Frage).
Aus Performancegründen und der Anforderung heraus garantiert deine Methode keine Konstanz in der Spaltenfolge.
Du kannst also nicht garantieren, ob P1Count = 3 auch immer dem Schlüssel 102 entspricht.
Da die Spaltennamen aber nur konstant zugewiesen werden können, macht es eher Sinn den konstanten Wert zu zählen und in der Spalte X dann NULL auszuweisen.
Außerdem vereinfacht es den SQL.

Sum(Case When P1Count = 1 Then 1 Else 0 End) "Anzahl 100",
Sum(Case When P1Count = 2 Then 1 Else 0 End) "Anzahl 101",
Sum(Case When P1Count = 3 Then 1 Else 0 End) "Anzahl 102",
Sum(Case When P1Count = 4 Then 1 Else 0 End) "Anzahl 103",

vs:

count(case p1 when 101 then 1 end) "Anzahl 101"

Aber wie immer, es gibt viele Wege zur Lösung.

ILEMax
03-09-20, 09:21
Ich verwende Birgittas Lösung, da ich die Spaltennamen und Anzahl nicht kenne.
Wir haben das Excel Tool von Meinikat im Einsatz.
Damit gebe ich zunächst den Text (P2) aus der TB_P in die Spalte 3 im Ziel excel. Dabei drehe ich die Ausgabe, so das ich alle Werte in eine Zeile in verschiedene Spalten schreibe, anstatt alles in eine extra Zeile.
Danach schreibe ich den P1 Wert darunter, ebenfals gedreht.
Im letzten Export schreibe ich die frisch erzeugte View ab Spalte 1 darunter
Dummerweise sind in TB_P nicht ca 30 Sätze sondern mittlerweile 168!
Lt Fachabteilung wird das in den nächsten 2 Jahren auf ca 200 anwachsen. Soviel haben ich nun vorgesehen.
Ich weis zwar nicht wer ein Excel mit 200 Spalten ansehen will, aber das ist ja auch nicht meine Baustelle.

Vielen Dank für Eure Hilfe!
Der ILEMax

Fuerchau
03-09-20, 09:43
PS: Bei unserer BI-Lösung gehört sowas übrigens zum Standard (incl. Excelexport) und die Anzahl der Spalten ist dabei sogar dynamisch.