Autor |
Beitrag |
Der Jan
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: Fr 16.12.05 11:17
Hallo,
ich hab ein Problem bei einer SQL Abfrage bzw. weiss ich gar nicht, ob das, was ich vorhabe einfach mit SQL geht:
Tabelle "Raten", enthält Daten zu monatlichen Ratenzahlungen bei bestimmten Verträgen:
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9:
| CREATE TABLE RATEN ( RATEN_ID INTEGER NOT NULL, RATEN_NR INTEGER, RATEN_START_DAT D_DATUMNULL, RATEN_END_DAT D_DATUMNULL, RATEN_BETRAG D_ZAHL2KOMMANOTNULL, //monatliche Rate LEASING_VERTR_ID TINT, //Vertrags-ID RATEN_MONAT D_DATUMNULL ); |
Jetzt bräuchte ich eine Abfrage, mit der ich alle Raten eines Vertrages in eine Zeile bekomme.Allerdings nicht z.B. mittels SUM/GROUP, sondern jede Rate muß in eine Spalte.
Dafür habe ich eine Zieltabelle (RATEN2, wie sinnig  )
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8:
| CREATE TABLE RATEN2 ( VERTR_ID INTEGER NOT NULL, RATE01 D_ZAHL2KOMMA, RATE02 D_ZAHL2KOMMA, //undsoweiter RATE71 D_ZAHL2KOMMA, RATE72 D_ZAHL2KOMMA ) |
Wie könnte man das machen?
Moderiert von raziel: Code- durch SQL-Tags ersetzt
_________________ Gruß, Jan
|
|
noidic
      
Beiträge: 851
Win 2000 Win XP Vista
D7 Ent, SharpDevelop 2.2
|
Verfasst: Fr 16.12.05 11:33
Ist die Anzahl der Raten festgelegt? Dann ginge das mit n ( n = Anzahl der Raten ) Joins...
_________________ Bravery calls my name in the sound of the wind in the night...
|
|
Der Jan 
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: Fr 16.12.05 11:35
Nein. Es sind zwischen 12 und 72.
Wie würde das mit den n Joins aussehen?
_________________ Gruß, Jan
|
|
Der Jan 
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: Fr 16.12.05 12:47
ich habe mir überlegt, ob man das vielleicht mit einer (oder zwei) Stored Procedure hinkriegen könnte. So sinngemäß: (Pseudocode)
SQL-Anweisung 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| PROCEDURE wasweissich FOR SELECT LEASING_VERTR_ID FROM RATEN INTO :act_ID DO FOR SELECT LEASING_VERTR_ID, RATEN_BETRAG, RATEN_NR FROM RATEN INTO :temp_ID, :temp_BETRAG WHERE LEASING_VERTR_ID = :act_ID ORDER BY RATEN_NR DO IF(erster_datensatz) INSERT INTO RATEN2 (VERTR_ID, RATE01) VALUES (:temp_ID, :temp_BETRAG) ELSE UPDATE RATEN2 SET RATE_xx = :temp_BETRAG //hier Problem WHERE :temp_ID = :act_ID
SUSPEND; END; |
Ginge das prinzipiell so?
Ein Problem: wie setze ich das "RATE_xx" im ELSE-Zweig? Kann man hier evtl. mit Arrays arbeiten?
Moderiert von raziel: Code- durch SQL-Tags ersetzt
_________________ Gruß, Jan
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 16.12.05 12:56
Du musst eine 'Pivot-Tabelle' bauen:
Wenn das hier der Inhalt der Tabelle ist
ID NR WERT
1 1 10
1 2 20
1 3 30
2 1 10
3 2 20
Und Du willst eine Tabelle haben wie die hier:
ID WERT1 WERT2 WERT3
1 10 20 30
2 10 NULL NULL
3 NULL 20 NULL
Dann schreibst Du einfach:
SQL-Anweisung 1: 2: 3: 4: 5: 6:
| select [ID], sum (case when Nr=1 then Wert Else NULL end) as Wert1, sum (case when Nr=2 then Wert Else NULL end) as Wert2, sum (case when Nr=3 then Wert Else NULL end) as Wert3 from Tabelle group by [ID] |
Wenn Dein SQL-Server das 'case' nicht versteht (MSSQL verstehts), dann geht es so:
SQL-Anweisung 1: 2: 3: 4: 5: 6:
| select [ID], (select Sum (Wert) from Tabelle x where x.Nr = 1 and x.[ID] = t.[ID]) as Wert1, (select Sum (Wert) from Tabelle x where x.Nr = 2 and x.[ID] = t.[ID]) as Wert2, (select Sum (Wert) from Tabelle x where x.Nr = 3 and x.[ID] = t.[ID]) as Wert3 from Tabelle t group by [ID] |
Summieren deshalb, weil es (unabhängig von Deinem konkreten Fall) sein kann, das zu einer Nr und einer ID mehrere Werte existieren.
Das Wort 'Pivot' kommt von 'Drehen', weil man immer einen Teil der Tabelle um 90 Grad dreht (Alle Werte einer ID stehen in der Tabelle untereinander, im Pivot dann nebeneinander).
_________________ Na denn, dann. Bis dann, denn.
|
|
Der Jan 
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: Fr 16.12.05 15:25
Das hilft mir schonmal ein stückchen weiter. Allerdings isses bei mir nicht so direkt einsetzbar, da ich eine Spalte wie "NR" in deinem Beispiel nicht habe.
Vielmehr soll der entsprechende Wert aus der ersten passenden Zeile (mit der richtigen ID) in die erste Spalte, der zweite WErt in die zweite spalte usw.
_________________ Gruß, Jan
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 16.12.05 16:18
Ah... ok, ich dachte, die RATEN_NR wäre das..
Dann ist das nicht trivial. Aber mit SQL geht das trotzdem. Weil aber Dein Darstellungswunsch sich nicht mit deinen Daten deckt (hast ja keinen individuellen Ratenzähler je Vertrags_ID) musst Du etwas mehr tun:
Es gibt Komponenten ( www.devexpress.com, QuantumGrid 5), die können Master-Detail Beziehungen so ähnlich darstellen, ohne das man viel rumhantieren muss. Die Master-Tabelle sind die Verträge, die Details sind die Raten. Die Verträge werden untereinander, die Raten jedes Vertrages unterhalb der 'Vertragszeile' einfach nebeneinander dargestellt.
Wenn Du das selbst basteln willst, würde ich die gesamte Tabelle in Delphi einlesen, und in einem geeigneten Grid, oder einer lokalen Tabelle (ADO mit Texttreiber und LockType=ltBatchOptimistic, dann ist es ein In-Memory-Dataset  selbst generieren:
Sei 'T' die lokale Tabelle
Quelltext 1: 2: 3: 4:
| ForEach Record r do T.Locate ('Vertrag_ID',r.ID,[]); F := FindNullRatenField (T); F.AsInteger := R.Rate |
Für jede Zeile in der Raten-Tabelle suchst Du die Zeile mit dem Vertrag (oder erzeugst eine neue, per append). Dann suchst Du in dem Record das erste RatenXX-Feld, das noch nicht befüllt ist und packst da den Wert rein.
Natürlich kannst Du das auch in SQL-Coden. Aber nur, wenn Du den Server ärgern willst.
_________________ Na denn, dann. Bis dann, denn.
|
|
Der Jan 
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: Di 20.12.05 11:33
Danke für die Hilfe.
Ich glaube, ich will den Server ärgern
Nee, mal im Ernst... Ich kann hier mit Delphi nicht wirklich ran, drum muß es in SQL sein, aber nun krieg ich es hin. 
_________________ Gruß, Jan
|
|
|