Hi, ich suche wiedermal Hilfe zu einer SQL Abfrage.
Ich habe eine Tabelle mit einer Spalte "Einnahmen" und einer Spalte "Ausgaben". Nun möchte ich eine dritte Spalte mit dem errechneten Saldo je Zeile. Ist das möglich?
mfg Anwender

Hi, ich suche wiedermal Hilfe zu einer SQL Abfrage.
Ich habe eine Tabelle mit einer Spalte "Einnahmen" und einer Spalte "Ausgaben". Nun möchte ich eine dritte Spalte mit dem errechneten Saldo je Zeile. Ist das möglich?
mfg Anwender
Ja.
ALTER TABLE <table_name>
   ADD saldo <column_type>;
Ich versteh nicht ganz. Könntest du mir ein Bespiel machen?
Tabellenname: tblSaldo
Spalte Einnahmnen: ein
Spalte Ausgaben: aus
Wäre für mich verständlicher. Danke
Die errechnete Spalte muss nicht in der DB gespeichert werden. Sie dient nur der Anzeige.
Okay ... (?)
Vermutlioch hast Du die Tabelle so ähnlich erzeugt:
CREATE TABLE tblSaldo(
   ein float,
   aus float );
ALTER TABLE tblSaldo
   ADD saldo float;
INSERT INTO tblSaldo( ein, aus, saldo ) VALUES( 1023.05, 23.05, 1000 );
INSERT INTO tblSaldo( ein, aus ) VALUES( 1023.05, 23.05 );
Danke für deine Ausführungen. Ich habe mir das anders vorgestellt:
Ich habe eine AccessDB mit einer Tabelle (tblSaldo) die 2 Spalten (Ein, Aus) enthält. Ich mache in VB nun eine Abfrage auf diese Tabelle und zeige das Resultat in einen DataGrid an. In der Abfrage möchte ich automatisch den Saldo auf jeder Zeile berechnen. Das sieht so aus: Einnahmen - Ausgaben = Saldo. Beim nächsten Datensatz dann: Den Saldo des vorherigen Datensatzes + Einnahmen - Ausgaben = neuer Saldo. Und das die ganze Tabelle durch.
Diese errechnete Spalte wird dann als dritte Spalte im DataGrid angezeigt aber nicht in die Datenbank geschrieben.
Ist das so überhaupt möglich in einer Abfrage zu lösen?
Anwender
Ja, ich denke schon. Ich habe sowas schon mit VBA gemacht:
   Me.ListeSaldo.RowSource = "SELECT ein, aus FROM tSaldo"
   Me.ListeSaldo.Requery
   ... jetzt berechnen etc.
So oder so ähnlich hat das funktioniert.
Mit zusätzlicher Spalte und UPDATE würde es so funktionieren.
Ich habe das schnell mit Oracle und SqlPlus ausprobiert, beachte das UPDATE Statement:
SQL> create table t_saldo( ein float, aus float, saldo float );
Table created.
SQL> desc t_saldo;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EIN                                                FLOAT(126)
 AUS                                                FLOAT(126)
 SALDO                                              FLOAT(126)
SQL> insert into t_saldo( ein, aus ) values( 1023.05, 23.05 );
1 row created.
SQL>Â commit;
Commit complete.
SQL> select * from t_saldo;
       EIN        AUS      SALDO
----------Â ----------Â ----------
   1023.05      23.05
SQL> update t_saldo set saldo = ein - aus;
1 row updated.
SQL>Â commit;
Commit complete.
 Â
SQL> select * from t_saldo;
       EIN        AUS      SALDO
----------Â ----------Â ----------
   1023.05      23.05       1000
Das müsste eigentlich auch mit Access Jet-SQL funktionieren.
d-oli
Für den Saldo des ersten Datensatzes zu berechnen ist das ok.
Aber für alle weitere Datensätze den Saldo zu berechnen, verstehe ich immer noch nicht.
Datensatz ----- Ein------- Aus -------Saldo
1 --------- 1023.05 ---- 23.05 ---- 1000.00
2 ------------54.00 ----------------????.??
3 ---------------------- 12.35 ---- ????.??
4 --------------------- 231.90 ---- ????.??
(Schlechte Formatierung :)
Es muss ja immer der Saldo des vorherigen Datensatzes berücksichtigt werden um den aktuellen Datensatz zu berechnen.
Wie würdest du das machen?
Anwender
Hmmm ... könnte es sein, dass die Tabelle immer nur eine Zeile haben soll?
In diesem Fall würde das so funktionieren:
   -- Datensatz1 Ein 1023.05 Aus 23.05 Saldo 1000.00
   insert into t_saldo( ein, aus ) values( 1023.05, 23.05 ); commit;
   -- Datensatz2 Ein 54.00 Saldo ????.??
   update t_saldo set ein = ein + 54.00; commit;
   update t_saldo set saldo = ein - aus; commit;
   -- Datensatz3 Aus 12.35 Saldo ????.??
   update t_saldo set aus = aus + 12.35; commit;
   update t_saldo set saldo = ein - aus; commit;
   -- Datensatz4 Aus 231.90 Saldo ????.??
   update t_saldo set aus = aus + 231.90; commit;
   update t_saldo set saldo = ein - aus; commit;
Andererseits könntest Du auch mit der Funktion SUM() arbeiten um damit den Datengrid zu füllen (siehe auch vorangehende angepasste Antwort betreffend VBA):
SQL>
   -- Datensatz1 Ein 1023.05 Aus 23.05 Saldo 1000.00
   insert into t_saldo( ein, aus ) values( 1023.05, 23.05 ); commit;
   -- Datensatz2 Ein 54.00 Saldo ????.??
   insert into t_saldo( ein, aus ) values( 54.00, 0 ); commit;
   -- Datensatz3 Aus 12.35 Saldo ????.??
   insert into t_saldo( ein, aus ) values( 0, 12.35 ); commit;
   -- Datensatz4 Aus 231.90 Saldo ????.??
   insert into t_saldo( ein, aus ) values( 0, 231.90 ); commit;
VBA>
   Me.ListeSaldo.RowSource = "SELECT SUM( ein ), SUM( aus ) FROM tSaldo"
   Me.ListeSaldo.Requery
d-oli
Ich muss jetzt leider gehen, sollte noch was sein, werde ich mir das morgen ansehen ... ;-)
Gruss
d-oli
Am liebsten würde ich das nur mit einem SELECT machen und ohne UPDATE, INSERT und ALTER TABLE.
Ich will den Saldo nicht in der Tabelle führen, nur zur Laufzeit errechnen und darstellen
SELECT Tab.einnahme, Tab.ausgabe, ([einnahme]-[ausgabe]) AS Summe
FROM Tab;
Nein! So wird nur die Summe pro Datensatz errechnet. Ich brauche aber die laufende Summe (Aufgerechnet der Summen verherigen Datensätze).
Okay, dann so wie schon beschrieben:
SQL>
-- Datensatz1 Ein 1023.05 Aus 23.05 Saldo 1000.00
insert into t_saldo( ein, aus ) values( 1023.05, 23.05 ); commit;
-- Datensatz2 Ein 54.00 Saldo ????.??
insert into t_saldo( ein, aus ) values( 54.00, 0 ); commit;
-- Datensatz3 Aus 12.35 Saldo ????.??
insert into t_saldo( ein, aus ) values( 0, 12.35 ); commit;
-- Datensatz4 Aus 231.90 Saldo ????.??
insert into t_saldo( ein, aus ) values( 0, 231.90 ); commit;
VBA>
Me.ListeSaldo.RowSource = "SELECT SUM( ein ), SUM( aus ), 0 FROM tSaldo"
Me.ListeSaldo.Requery
Die "0" in "SELECT SUM( ein ), SUM( aus ), 0 FROM tSaldo" steht für den leeren Saldo, den Du berechnen und im DatenGrid nachführen musst.
So, ich gehe jetzt an die Sonne ... ;-) ... bis ev. morgen.
d-oli
So ähnlich habe ich mir das vorgestellt. Hab das jetzt noch nicht ausprobiert, mach ich aber noch.
Ich habe im Internet etwas über einen Lösungsansatz mit der Funktion DSUM() (http://support.microsoft.com/?kbid=290136) gelesen. Kann das für meinen Fall aber nicht richtig interpretieren. Wäre das evt eine Lösung?
mfg Anwender
Die Access Hilfe hilft in diesem Fall nicht weiter.
Habe deine Abfrage von oben implementiert und sie funktioniert so wie ich mir das vorstelle. Vielen Dank!
Einziger Nachteil: bei meinen 4000 Datensätzen dauert die Abfrage nun volle 14 Sekunden! Naja war wohl zu erwarten.
Wenn es aber eine effizientere Möglichkeit gibt, wär ich natürich dankbar für weitere Infos.
mfg Anwender
Nur so als Anmerkung: Für Geldbeträge sollte man tunlichst keine float-Felder einsetzen sondern Grundsätzlich Ganz oder Festkommazahlen. Rechenungenauigkeiten sind bei solchen Anwendungen eine sehr böse Sache...
Gruß
Borlander
Ja, klar. Ich habe das weggelassen damit nicht noch ein Diskusion ob jetzt numeric(p,s) oder decimal(p,s) und warum nicht doch real, double oder float und wie viel Stellen vor dem Komma denn nun und gibt es denn nicht auch RDBMS die den Datentypen CURRENCY unterstützen ... und und und ... uff, kennst Du das auch?
Meiner Ansicht ist der grösste Schwachpunkt sowieso, dass kein Primärschlüssel vorhanden ist. Bei einer (doppelten) Buchhaltung müssten alle Buchungen mit einer Buchungsnummer versehen werden die eindeutig sein sollte (=Primärschlüssel). Auch ein Datum gehört meiner Ansicht nach zu einer Buchung. Aber das ginge hier wohl zu weit.
Gruss
d-oli
ID (Primärschlüssel), Datum, Valuta, Buchungstext, ... alles vorhanden. Wollte nur das Beispiel einfach halten.
mfg Anwender
Na dann ... ;-)
Für komplexere Sachen ist es manchmal besser mehr zu erfahren.
Ich würde übrigens die Lösung mit einer zusätzlichen Spalte "Aktueller Saldo" und dem Nachführen des aktuellen Saldos per Trigger bevorzugen.
Gruss
d-oli