Datenmodell für Wasserverbrauch?

Ich möchte den Wasserverbrauch in einer Datenbanktabelle festhalten und bei Bedarf auslesen können. Wie sollte die Tabelle aussehen:

Tabelle: Wasser_verbrauch

Ablese\_Datum Zählerstand 
01.12.01 103 
06.12.01 154
09.12.01 189
14.12.01 219

Wie kann ich allgemein den Wasserverbrauch pro Tag für den Zeitraum z.B. zwischen 6 und 9 Dezember mit SQL ausrechnen?

Oder ist folgendes Modell besser:

Tabelle: Wasser\_verbrauch 
Datum\_1 Zählerstand\_1 Datum\_2 Zählerstand\_2
01.12.01 103 06.12.01 154
06.12.01 154 09.12.01 189
09.12.01 189 14.12.01 219
14.12.01 219 .....

Der Verbrauch kann einfach ausgelesen werden. Entspricht dies Modell noch der 1. bis 3. Normalform?

gruß
Peter

Tabelle: Wasser_verbrauch

Ablese_Datum Zählerstand
01.12.01 103
06.12.01 154
09.12.01 189
14.12.01 219

Das reicht völlig aus - der andere Vorschlag war sehr schlecht.

Nötig ist jetzt nur noch ein wenig SQL, das hängt aber wiederrum vom RDBMS ab. Was benutzt du denn ?

Gruß der Janus

Tabelle: Wasser_verbrauch

Ablese_Datum Zählerstand
01.12.01 103
06.12.01 154
09.12.01 189
14.12.01 219

Das reicht völlig aus - der andere Vorschlag war sehr
schlecht.

Nötig ist jetzt nur noch ein wenig SQL, das hängt aber

wiederrum vom RDBMS ab. Was benutzt du denn ?

Gruß der Janus

Hallo Janus,

ich benutze Oracle 8i. Wie kann ich den Verbrauch am besten abfragen? Danke.

Frohes Neues Jahr
Peter

Hallo Peter,

ich benutze Oracle 8i. Wie kann ich den Verbrauch am besten
abfragen? Danke.

Am besten mit PL/SQL:

DECLARE

v_zaehler_start wasser_verbrauch.zaehlerstand%TYPE;
v_zaehler_ende v_zaehler_start%TYPE;
v_datum_start DATE := TO_DATE(’&startdatum’,‚DD-MON-YYYY‘);
v_datum_ende DATE := TO_DATE(’&endedatum’,‚DD-MON-YYYY‘);
v_verbrauch_gesamt NUMBER;
v_verbrauch_avg NUMBER;
v_tage_anzahl NUMBER;

BEGIN

SELECT zaehlerstand
INTO v_zaehler_start
FROM wasser_verbrauch
WHERE ROUND(ablese_datum) = v_datum_start;

SELECT zaehlerstand
INTO v_zaehler_ende
FROM wasser_verbrauch
WHERE ROUND(ablese_datum) = v_datum_ende;

v_verbrauch_gesamt := v_zaehler_ende - v_zaehler_start;
v_tage_anzahl := v_datum_ende - v_datum_start;
v_verbrauch_avg := v_verbrauch_gesamt / v_tage_anzahl;

DBMS_OUTPUT.PUT_LINE('Verbauch fuer ‚|| v_tage_anzahl ||‘ Tage : '||v_verbrauch_gesamt);
DBMS_OUTPUT.PUT_LINE(‚Verbrauch im Tagesschnitt :‘|| v_verbrauch_avg);

END;
/

Wenn du noch Fragen hast, dann können wir die bestimmt klären.

Gruß der Janus

1 „Gefällt mir“

Hallo Janus,

toll, vielen Dank.

Gruß
Peter

P.S. Ich weiß leider noch nicht genau, wie das mit den Bewertungspunkten funktioniert. 1 Punkt ist eigentlich zu wenig.

Hi Peter!

Eine etwas allgemeinere Lösung, dafür aber u. U. weniger performante Lösung (ohne PL/SQL) wäre folgender SELECT:

SELECT alt.datum AS beginn, 
 neu.datum AS ende, 
 neu.stand - alt.stand AS verbrauch, 
 (neu.stand - alt.stand)/(neu.datum - alt.datum) AS tagesverbrauch
FROM my\_table alt, my\_table neu
WHERE alt.datum=
 (SELECT MAX(datum) 
 FROM my\_table sub 
 WHERE sub.datum

Außerdem solltest Du nicht vergessen, die Tabelle zu indizieren.
Noch allgemeiner kannst Du Daten mit folgendem View abfragen:


    
    CREATE VIEW my\_view AS
    SELECT alt.datum AS beginn, 
     neu.datum AS ende, 
     neu.stand - alt.stand AS verbrauch 
    FROM my\_table alt, my\_table neu 
    WHERE neu.datum \> alt.datum;




den Du dann z.B. mittels


    
    SELECT \* 
    FROM my\_view 
    WHERE to\_char(beginn,'DD.MM.YYYY')='20.12.2001' AND
     to\_char(ende,'DD.MM.YYYY')='03.01.2001';



aufrufst. Dadurch kannst Du dann für beliebige Zeiträume (nicht nur zwischen jeweils zwei Ablesungen) den Verbrauch ermitteln.

Das ganze ließe sich jetzt natürlich noch (fast) ewig fortsetzen.

Gruß,
Martin