Frage zur Formulierung einer Query

Hallo,
ich bin gerade dabei ein Programm zu schreiben, welches auf eine SQL-Datenbank zugreift. Es funktioniert auch alles, nur leider werden soviele Queries erzeugt, dass die Geschwindigkeit schon ziemlich leidet.
Das Programm soll aus einer Tabelle die aussieht wie folgt:
timestamp | wert
1 | 20
2 | 30
3 | 10
4 | 40
5 | 30
6 | 200
usw.

immer z.B. die ersten 5 Werte zusammenfassen d.h. aus diesen Werten den maximalen Wert nehmen, so dass die Tabelle so aussieht:

1 | 40
usw.

Nun soll es aus diesen resultierenden Werten den Durchschnitt bei gegebener timestamp bilden. So dass, wenn ich z.B. den Durchschnitt fuer timestamp 5 anfordere mit einem Intervall von 3, der Wert von 5,4,3 genommen wird, alles addiert wird, durch 3 geteilt und zurueckgeliefert.

Puuuh ich hoffe ich hab mich bis jetzt einigermassen verständlich ausgedrückt

Ich habe das ganze nun so programmiert:

fasseimmer5Wertezusammen(timestamp) 
{ 
     query:hole 5 werte und ermittle das maximum 
     return maximalwert 
} 

ermittledenDurchschnitt(timestamp, intervall) 
{ 
     for(int i=timestamp-intervall, i<=timestamp, i++) 
     { 
           ergebnis+=fasseimmer5Wertezusammen(i) 
     } 
   return ergebnis/i
}

Wie ihr euch vorstellen koennt braucht das ganze queries ohne Ende und laeuft grotten-langsam.
Nun meine eigentliche Frage: kann man das “5-werte zusammenfassen” und “aus mehreren dieser 5er-Werte den Durschnitt bilden” nicht in eine einzige Query verpacken?

Hoffe ich hab mich klar genug ausgedrückt, dass mit jemand helfen kann auf jedenfall vielen Dank schonmal…[/code]

Hallo mcrip,

ist das eine PostgreSQL-Datenbank?



mfg

fristo

Ja, genau.
Hier noch der richtige Sourcecode aus meinem Programm:
also die SELECT-Anweisung ist bei mir ein bisschen fragmentiert, da die tabelle aus mehreren Werten und einer timestamp besteht und ich, wenn nichts gelesen werden konnte (keine Werte zur timestamp vorhanden), das ganze mit 0en auffuellen moechte(dazu wird das open gesucht, wenn das nicht vorhanden ist, wird davon ausgegangen, dass keine Werte zu der timestamp vorliegen) trotzdem mal der code:

ohlc *Datenbank::giveOHLC(string Symbol, int timestamp, int type)
{
  timestamp=timestamp-timestamp%(type*60);
  ohlc *OHLC = new ohlc;
  work action(*Conn);
  result r;
  bool open=false;
  bool close=false;
  //Suche des Open
  r=action.exec("SELECT open, close FROM \"" + Symbol + "_3\" WHERE timestamp >" + IntToString(timestamp-60) + " AND timestamp<" + IntToString(timestamp+type*60) +";");
  if(r.size()!=0)
    {
      for(int i=0; i<type>open))
	    {
	      open=true;
	      i=type;
	    }
	}
    }
  
  if(open)
    {
      //Suche des Close
      if(r.size()!=0)
	{
	  for(int i=type-1; i>-1; i=i-1)
	    {
	      if(r[0]["close"].to(OHLC->close))
		{
		  close=true;
		  i=-1;
		}
	    }
	}
      //High/Low holen
      r=action.exec("SELECT max(high), min(low), sum(volume) FROM \"" + Symbol + "_3\" WHERE timestamp > " + IntToString(timestamp-60) + "AND timestamp<IntToString>high))
	OHLC->high=0;
      if(!r[0]["min"].to(OHLC->low))
	OHLC->low=0;
      if(!r[0]["sum"].to(OHLC->low))
	OHLC->volume=0;
      OHLC->timestamp=timestamp;
    }
  else
    {
      OHLC->timestamp=0;
      OHLC->open=0;
      OHLC->close=0;
      OHLC->high=0;
      OHLC->low=0;
      OHLC->volume=0;
    }
  action.commit();
  return OHLC;
}

diese Methode erzeugt bei mir im Moment immer 5er-Paeckchen (wenn timestamp nicht vorhanden ist, wird der Wert, welcher zurueck geliefert wird mit 0en aufgefuellt), welche spaeter von einer anderen Methode abgefragt werden und verarbeitet (es werden x-viele 5-er-Paeckchen nach einander abgefragt und aus ihnen der Durchschnitt errechnet).
Die Methode ist so geschrieben, dass type angibt aus wieviel timestamps ein Paeckchen gebildet wird(5er, 6er etc.).
Die Schleife in der Methode, springt sozusagen immer von 5er-Paecken zu 5er-paecken und bestimmt die minima/maxima, summen. Fuer jeden Sprung ist halt eine SQL-Query faellig, deshalb ist es so langsam. Ist es moeglich so einen Schleife in eine SQL-Query zu packen? Also so dass ich als Ergebnis der Query gleich mehrere Paeckchen bekomme und daraus somit auf einmal den Durchschnitt erechnen kann ohne fuer jedes paeckchen 2 queries rauszuschicken.

Ich hoffe das hilft weiter. Vielen Dank schonmal.

Hallo mcrip,

den zeitlichen Aufwand, den das Program zur Auswertung benötigt, ist abhängig von von der Anzahl der Datensätze und der Intervallgröße. Da die Auswertung in der Applikation erfolgt, kommen noch die Zeiten für den Tranfer der Daten hinzu. Und diese dürften auch nicht unerheblich sein.

Besser wäre es die Auswertung auf den Server zu verlagern und dort mittels der Sprache plpgsql eine Funktion zu erstellen. Grob angedacht würde ich wie folgt vorgehen. An die Tabelle eine Spalte für eine Gruppenkennzeichnung anfügen. Die Gruppenkennzeichnung wird in Abhängigkeit von der Intervallgröße erstellt. Z. B. Intervallgröße 5: Die ersten 5 Datensätze erhalten den Wert 0, die zweiten 5 Datensätze erhalten den Wert 1, die dritten 5 Datensätze erhalten den Wert 3, usw. Anschließend kann mit einem einfachen SELECT den max. Wert jeder Gruppe berechnet werden, in dem man die Gruppierung in dem SELECT einbaut.

PS: Entspechend der Angabe für den RETURN der Funktion, liefert die Funktion entweder nur einen oder alle Werte zurück.



mfg

fristo

und wie kann ich so eine Index-Spalte erstellen, welche immer 5 Datensaetze zusammenfast?
Waere es auch moeglich, dass die Methode gleich alle 5-erPaeckchen, welche von Intervall bestimmt werden zurueckliefert? So dass die Methode, welche am ende den Mittelwert erstellt auf einmal alle Daten anfragen kann, anstatt in einer Schleife immer von Paeckchen zu Paeckchen zu gehen?
Eine query muesst dazu die Daten in 5er-Paeckchen teilen und dann immer das max,min usw. zurueckliefern. Ich habe nur nicht die geringste Ahnung wie man eine solche Query baut.

Hallo mcrip,

Ich schließe mal daraus, dass Du die SQL-Sprache nicht beherrscht. Dies ist aber unbedingt notwendig um eine Datenbank zu programmieren. Es wird Dir daher nichts anderes übrig bleiben, als erstmal die SQL-Sprache zu lernen.

Es hilft Dir nichts wenn ich Dir weiter etwas erkläre, was Du dann doch nicht verstehst. Für jemand, der die entsprechenden Kenntnisse der SQL-Sprache hat, hätte der beschriebene Lösungsansatz ausgereicht.



mfg

fristo