Autor Beitrag
fahrstuhl65
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Mi 12.10.11 16:12 
Hallo,

ich habe eine MSSQL DB die ein etwa so ausschaut:

DateTime LastTrade Volume
2011-03-17 09:06:09.000 6598.5 2
2011-03-17 09:06:09.000 6599 1
2011-03-17 09:06:10.000 6599 1
2011-03-17 09:06:11.000 6599 5
2011-03-17 09:06:11.000 6599 1
2011-03-17 09:06:11.000 6598.5 1
2011-03-17 09:06:12.000 6599 1

Für jede Minute gibt es einige, manchmal ein paar hundert Zeilen in denen ein Kurs steht (LastTrade).

Nun möchte ich herausfinden was das jeweilige Hoch und Tief einer Minute ist
und das Ergebnis in eine neue Tabelle wie folgt schreiben:

DateTime Hoch Tief
2011-03-17 09:06:00.000 6598.5 6580
2011-03-17 09:07:00.000 6593 6590
2011-03-17 09:08:00.000 6593 6590

Ich hab nur leider keine Ahnung wie ich das bewerkstelligen soll - kann mir da jemand helfen ?

ich such keine fertige Lösung, nur einen Weg den ich dann versuchen kann zu gehen :D

Die Datenbank über die ich das machen muss hat ca. 10 Millionen Datensätze.

Freue mich auf Hilfe

gruß
fahrstuhl
Horschdware
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 744
Erhaltene Danke: 54

Win XP Pro, Win 7 Pro x64
Delphi 7, Delphi XE, C++ Builder 5, SAP R/3
BeitragVerfasst: Mi 12.10.11 16:21 
Ich gehe mal davon aus, du suchst nur nach den passenden SQL-Befehlen, ja?
Dann bekommst du die Maxima und Minima wie folgt:
ausblenden Quelltext
1:
2:
3:
SELECT max(LastTrade) AS maximum, min(LastTrade) AS minimum
FROM btlWieAuchImmer
WHERE DateTime = GewünschterZeitpunkt


Dann für jeden Zeitpunkt einen neuen Eintrag in der zweiten Tabelle anlegen.

_________________
Delphi: XE - OS: Windows 7 Professional x64
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 12.10.11 16:30 
Hallo,

das Problem ist die Spalte 'DateTime', da dort ja unterschiedliche Sekunden eingetragen sind, aber nur nach Minuten gruppiert werden soll.
Evtl. helfen dazu die Date and Time Functions (Transact-SQL).

Edit: unter ask.metafilter.com/4...QL-results-by-minute scheint es gute Ansätze dafür zu geben (DATEPART, CONVERT, DATEDIFF)...


Zuletzt bearbeitet von Th69 am Mi 12.10.11 16:39, insgesamt 1-mal bearbeitet
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Mi 12.10.11 16:34 
@ Horschdware

ja danke - das wäre ein gangbarer Weg denke ich !
Ich werde mich mal dran wagen und hab dann sicher noch ein paar Fragen :D

@ TH69

das ist in der Tat richtig, gibt es denn für den oben genannten SQL Query auch die Möglichkeit

Between 16032011 08:00.00.000 AND 16032011 08.00.59.999 zu suchen ?
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 12:03 
Also das mit dem Between suchen funktioniert nun mit diesem Query:

ausblenden SQL-Anweisung
1:
2:
3:
SELECT        MAX(LastTrade) AS maximum
FROM            datei1
WHERE        (DateTime BETWEEN @p1 AND @p2)


Für @p1 und @p2 übergebe ich dann die Zeiträume.
Gebe ich das das per Hand ein, funktioniert die Abfrage, aber im Code habe ich folgendes stehen:


ausblenden C#-Quelltext
1:
2:
3:
4:
5:
string maximum;

DateTime beginn = new DateTime(20110317090600000);
DateTime ende = new DateTime(20110317090659999);  
maximum = GesamtdatenTableAdapter_button1_click.maximumabfrage(beginn, ende);


Versuche ich zu kompilieren, zeigt er mir:

Fehler 1 Der Typ "object" kann nicht implizit in "string" konvertiert werden. Es ist bereits eine explizite Konvertierung vorhanden. (Möglicherweise fehlt eine Umwandlung.)

Das man da was casten muss, ist mir eigentlich klar, aber ich weiss beim besten willen nicht wie,
in string casten geht nicht und hier hake ich echt grade, ich denke das ist total banal, aber ich
komm da grade nicht weiter.

Kann mir einer weiterhelfen ?


Zuletzt bearbeitet von fahrstuhl65 am Do 13.10.11 13:03, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 13.10.11 12:28 
Die MAX Aggregatfunktion liefert sicher keinen string sondern einen Zahlenwert entsprechend dem Typ von LastTrade. Wie sieht den die MethodenSignatur von maximumabfrage aus und welchen Typ hat LastTrade?
Allgemein würde ich von casten in diesem Kontext abraten sondern du solltest einen expliziten Aufruf von Convert.ToMeinKonkreterZielTyp vornehmen (wenn den überhaupt nötig).

PS. Stilfragen. Du hast einen TableAdapter mit '_button1_click' im Namen? Du schreibst Methoden klein?
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 12:34 
also die Column LastTrade in der DB hat Varchar als Datentyp - also sollte das doch passen ?

Ich hab ja sowas hier auch schon versucht:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
            string maximum;
            // string minimum;

            DateTime beginn = new DateTime(20110317090600000);
            DateTime ende = new DateTime(20110317090659999);  
            
            maximum = GesamtdatenTableAdapter_button1_click.maximumabfrage(Convert.ToString(beginn), Convert.ToString(ende));


Mit dem Ergebnis:

Argument: Kann nicht von "string" in "System.DateTime?" konvertiert werden.

zu den Stilfragen, ja das mit dem TableAdaptern habe ich nur gemacht um zu wissen aus welcher Funktion der TableAdapter
aufgerufen wurde, falls mal ne Exception geworfen wird, ist sicher kein guter Stil, hat mir aber schon mehrfach geholfen.
Das mit den Methoden, ich bin halt noch Anfänger :D


Zuletzt bearbeitet von fahrstuhl65 am Do 13.10.11 13:03, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 13.10.11 12:46 
Zitat:
also die Column LastTrade in der DB hat Varchar als Datentyp - also sollte das doch passen ?


Nun ja wenn dir bewußt ist was das Maximum einen strings bedeutet ist das ok (z.B.ist '2' maximaler als '10' und bei einem Datum in einem string hast du die gleiche Problematik)

Zitat:
maximum = GesamtdatenTableAdapter_button1_click.maximumabfrage(Convert.ToString(beginn), Convert.ToString(ende));


Ich dachte eher der AusgabeTyp wäre das Problem nicht die Eingabeparameter. Zeig lieber mal die Methodensignatur von maximumabfrage.
Und nur nochmal zur Zusammenfassung LastTrade ist ein varchar und dein Feld DateTime ist tatsächlich auch vom Typ DateTime oder ist das auch ein varchar und heißt nur Datetime? Dann Viel Spass :roll:
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 13.10.11 12:53 
Hallo fahrstuhl65,

bitte formatiere deine Beiträge mit den entsprechenden Tags (SQL, C#, etc.). Dazu kannst du deine Beiträge editieren und mit der ComboBox aus "Bereiche" den entsprechenden Tag auswählen und dann den "+"-Button drücken.

Danke.
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 13:00 
Du hast natürlich Recht - eigentlich müsste die Column auch auf float oder ähnliches
gesetzt sein, in den Tests hats aber funktioniert bisher, ändere ich aber noch mal !
War mir so noch nicht bewusst :D

Das Feld DateTime ist tasächlich vom Typ DateTime in der DB - das habe ich beim Import
schon so hinbekommen.

Aber was meinst du mit der "Methodensignatur" - wo finde ich die ?
Stehe im Moment auf dem Schlauch....
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 13.10.11 13:31 
Ich will wissen wie die maximumabfrage Methode aussieht.
Also irgendwie sowas

ausblenden C#-Quelltext
1:
public string maximumabfrage(DateTime p1, DateTime p2)					
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 13:54 
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
public virtual object maximumabfrage(global::System.Nullable<global::System.DateTime> p1, global::System.Nullable<global::System.DateTime> p2) {
            global::System.Data.SqlClient.SqlCommand command = this.CommandCollection[1];
            if ((p1.HasValue == true)) {
                command.Parameters[0].Value = ((System.DateTime)(p1.Value));
            }
            else {
                command.Parameters[0].Value = global::System.DBNull.Value;
            }
            if ((p2.HasValue == true)) {
                command.Parameters[1].Value = ((System.DateTime)(p2.Value));
            }
            else {
                command.Parameters[1].Value = global::System.DBNull.Value;
            }
            global::System.Data.ConnectionState previousConnectionState = command.Connection.State;
            if (((command.Connection.State & global::System.Data.ConnectionState.Open) 
                        != global::System.Data.ConnectionState.Open)) {
                command.Connection.Open();
            }
            object returnValue;
            try {
                returnValue = command.ExecuteScalar();
            }
            finally {
                if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
                    command.Connection.Close();
                }
            }
            if (((returnValue == null
                        || (returnValue.GetType() == typeof(global::System.DBNull)))) {
                return null;
            }
            else {
                return ((object)(returnValue));
            }
        }


Das steht im Designer - ist ja eine automatisch generierte Abfrage, meinst du das ?
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 14:06 
Ach ich habs,....sorry.....

so ists richtig:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
            string maximum;
            
            DateTime beginn = new DateTime(20110317090600000);
            DateTime ende = new DateTime(20110317090659999);  
            
            maximum = Convert.ToString(GesamtdatenTableAdapter_button1_click.maximumabfrage(beginn, ende));


Das was zurückgegeben wird muss in den String umgewandlet werden :D

So, nun bin ich wieder einen Schritt weiter, nun muss ich mal versuchen wie ich es hinbekomme eine Schleife zu basteln,
die a) immer den Wert der beginn und ende zugewiesen wird um 1 erhöht und b) das ergebnis in eine neue
Datenbank schreibt um dann irgendwann da hinzukommen wo ich hin will :D

Aber - einen Schritt bin ich dann doch schon mal weiter ! Wenn jemand eine Idee für die Schleife hat,
freu ich mich natürlich !
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 14:13 
btw - ich hab jetzt auch die Spalte Lasttrade vom Typ her auf "float" gewechselt :D
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 13.10.11 16:13 
Wenn ich dich richtig verstanden habe und du den Max/Min Wert je Minute willst brauchst du nicht mehrere Abfragen.
Ist in dem Fall sogar recht einfach da der SmallDateTime Datentyp zufällig (mehr oder weniger) genau ein Präzision von einer Minute hat. Einmal kurz hin und zurück casten und alle Daten sind auf die Minute normiert.

ausblenden SQL-Anweisung
1:
2:
3:
4:
select Max(LastTrade), Min(LastTrade), CAST(CAST([DateTime] as SmallDateTime) as DateTime)
  from datei1
 where [DateTime] between @p1 AND @p2
 group by CAST(CAST([DateTime] as SmallDateTime) as DateTime)

So bekommst du aber nur natürlich nur ein Ergebnis für Minuten in denen es auch Daten gibt. Beim selber 'hochzählen' der Minuten bekommst du natürlich auch leere Ergebnisse.


Zuletzt bearbeitet von Ralf Jansen am Do 13.10.11 16:55, insgesamt 2-mal bearbeitet
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 13.10.11 16:44 
Hall Ralf,

toller Trick - muß ich mir merken.
Du meinst aber sicher 'DateTime' anstatt 'LastTrade' in dem CAST in der oberen Zeile?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 13.10.11 16:51 
Zitat:
Du meinst aber sicher 'DateTime' anstatt 'LastTrade' in dem CAST in der oberen Zeile?


Nein. LastTrade scheint ein Kurswert zu sein kein Datum. Ich hatte es so verstanden das er seine DateTime Spalte tatsächlich DateTime genannt hat. Und wenn dem so ist sollte er spätestens jetzt gemerkt haben wie missverständlich das ist, Danke ;)

Edit: Jetzt sehe ich es auch. Im anderen Cast sollte es ebenfalls [DateTime] heißen nicht LastTrade. Wird korrigiert.
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Do 13.10.11 16:59 
naja mit dem LastTrade habt ihr schon Recht, könnte man missverstehen,
ich hab das aber so übernommen aus einem CSV :D

Es ist der letzte Kurs der festgestellt wurde zu dem jeweiligen Zeitpunkt.

Das mit dem Casten muss ich mir erstmal anschauen in Ruhe -
das habe ich so aus dem Stand noch nicht verstanden, muss nur leider jetzt weg,
melde mich morgen früh - danke erstmal !!!
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Fr 14.10.11 10:33 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich dich richtig verstanden habe und du den Max/Min Wert je Minute willst brauchst du nicht mehrere Abfragen.


WOW - du hast Recht, ich muss jetzt noch verifizieren ob das richtig ist was da rauskommt, es sieht aber sehr danach aus !
Vor allem - und das ist natürlich noch wesentlich besser als das was ich vorhatte, muss ich mich so nicht um die leeren Zeilen
am Ende wieder kümmern,....sondern er macht das nur für die Zeiten, die da sind scheinbar.

Und wenn ich WHERE... p1 und p2 wegnehme macht er das ja sofort über alle scheinbar.

Wahnsinn, ich werd jetzt mal verifizieren ob die Ergebnisse auch "stimmen",....melde mcih dann wieder!
fahrstuhl65 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 30



BeitragVerfasst: Fr 14.10.11 11:19 
zu früh gefreut :D Also das was er macht stimmt nur bedingt, es gibt immer eine Verschiebung
von 1 bis 1,5 Punkten,....warum hab ich noch nicht verstanden es gibt kein Muster.

Ziel ist es ja das Maximum und das Minimum JEDER Minute zu finden, wenn ich also folgende
Abfrage starte:

ausblenden SQL-Anweisung
1:
2:
3:
4:
5:
SELECT [DateTime]
      ,[LastTrade]
      ,[Volume]
      
  FROM [Fdax_bereinigt].[dbo].[datei1] WHERE DateTime BETWEEN '16/03/2011 09:05:00.000' AND '16/03/2011 09:05:59.999' order by LastTrade


dann erhalte ich als kleinsten Wert 6711 und als höchsten Wert 6715,5.

In dieser Abfrage hier:

ausblenden SQL-Anweisung
1:
2:
3:
select Max(LastTrade) AS Maximum, Min(LastTrade) AS Minimum, (CAST(CAST([DateTime] as SmallDateTime) as DateTime)) AS Datum
  from datei1
 group by CAST(CAST([DateTime] as SmallDateTime) as DateTime)order by Datum


die ich nur um die Bezeichner verändert habe sagt er mit für die Minute 09:05:00 dann 6711 und 6714

Warum das so ist, versteh ich jetzt noch nicht ganz, das liegt aber daran das ich nicht ganz verstehe was die untere Abfrage eigentlich macht :D

Wenn die untere Abfrage das exakt könnte, wäre das natürlich der Hit, müsste ich nichts programmieren und könnte dann zum letzten Schritt
über gehen, aber da stimmt ja noch etwas nicht, hat noch einer eine Idee ?