Verdichtung von Daten

Softi

Benutzer
Beiträge
19
Hallo,
folgende Sache möchte ich gern realisieren, aber ich weis
nicht genau wie:

Es existieren 3 Tabellen in einer MS SQL Express R2 Datenbank.

In Tab.1 werden zyklisch (jede Minute) Messwerte mit eigener ID und Zeitstempel
eingetragen.
Nun möchte ich das in Tab2 ein Art Verdichtung der Daten stattfindet.
Es sollen aus den Minutenwerten von Tab1, Stundenwerte als Mittelwerte in
Tab2 eigentragen werden.
Und in Tab3 Tagesmittelwerte von Tab2.
Tabelle 1 könnte dann jeden 2.Tag gelöscht werden um das Datenbankvolumen
gering zu halten.

Hat sowas schonmal jemand gemacht?:confused:
Bin für jeden Vorschlag dankbar.;)

Schönen Abend noch.
Gruß Softi
 
Werbung:

Charly

Datenbank-Guru
Beiträge
306
AW: Verdichtung von Daten

Hallo Softi,

könnte man genauso lösen wie ich in meinem letzten Beitrag unter Ringspeicher geschrieben habe.

Du schreibst dir eine SQL-Script-Datei und übergibst sie sqlcmd

Dann Sqlcmd in eine Batch-Datei packen und über den Taskplaner Stündlich oder Täglich ausführen lassen.

Gruß Charly
 

Softi

Benutzer
Beiträge
19
AW: Verdichtung von Daten

Hallo Charly,

Danke für dein Antwort.

Das wäre ne Möglichkeit. Leider
bin ich so aber sehr unflexibel.

Wenn ich es nun über ein VB Prog laufen lassen,
dann muss aber VB Programm dauerend laufen, oder:confused:

Könntest du mir evtl. noch nen Tip geben, wie
der SQL String ausehen muss.
Bin leider noch nicht so tief in der Materie um
das alleine lösen zu können:(

Schönen Abend!

Gruß
Softi
 

Charly

Datenbank-Guru
Beiträge
306
AW: Verdichtung von Daten

Hallo Softi,

da ich keine richtigen Testdaten und Tabellen hatte, habe ich mal Tabellen und Spieldaten erzeugt.

Soll ja alles funktionieren.

Tabellen erzeugen:

Code:
CREATE TABLE T1 
(
 IDX int identity(1,1),
 docEntry float DEFAULT RAND() * 10, 
 docDate datetime 
)
 
CREATE TABLE T2
(
 IDX int identity(1,1),
 Avg_H_Entry float ,
 docDate nchar(10) ,
 docHour int
)
 
CREATE TABLE T3 
(
 IDX int identity(1,1),
 Avg_D_Entry float ,
 docDate nchar (10) ,
)

Damit man später auch was sehen kann wird T1 mit Spieldaten gefüllt:

Code:
DECLARE @counter AS int
SET @counter = 1
SET NOCOUNT ON
WHILE @counter < 501
 BEGIN
  INSERT INTO T1 (docEntry, docDate) VALUES (default,getdate() - (rand() * 2))
  INSERT INTO T1 (docEntry, docDate) VALUES (default,getdate() - (rand() * 3))
  SET @counter = @counter + 1
 END
SET NOCOUNT OFF
GO

Damit beim ersten Lauf der INSERT-Anweisung auch Daten in T2 und T3 eingetragen werden muss ich erstmal inizialisieren:

Code:
INSERT INTO T2 (Avg_H_Entry, docDate, docHour) VALUES (0,'01.01.1990', '-1')
INSERT INTO T3 (Avg_D_Entry, docDate) VALUES (0,'01.01.1990')

So... Jetzt haben wir ca. 1000 Datensätze in T1 und jeweils einen in T2 und T3. Die braucht man damit das INSERT einen Bezugspunkt beim ersten Einfügen hat.

Hier nun das INSERT für T2:
Code:
INSERT INTO T2 
(
 Avg_H_Entry, 
 docDate, 
 docHour
)
SELECT 
 AVG(docEntry) AS avgStunde, 
 RTRIM(CONVERT(nchar,docDate,104)) AS docDate,
 DATENAME (hh,docdate) AS docHour
FROM T1
WHERE 
 DATENAME (hh,docdate) > 
 (
  SELECT docHour 
  FROM T2 
  WHERE IDX = 
  (
   SELECT MAX(IDX)
   FROM T2
  )
 )
GROUP BY 
 DATENAME (hh,docdate),
 RTRIM(CONVERT(nchar,docDate,104))


Ich bin nicht ganz glücklich mit den geschachtelten SELECT aber was will man machen...

Das INSERT für T2 fragt in T2 nach der Stunde des zuletzt eingefügten Datensatzes. Deswegen das etwas unübersichtliche WHERE. Du musst dieses INSERT auch nicht jede Stunde laufen lassen. Es werden einfach alle neuen Datensätze eingetragen .

Jetzt noch das INSERT für T3:

Code:
INSERT INTO T3 (Avg_D_Entry, docDate)
SELECT AVG(avg_H_Entry), docdate 
FROM T2
WHERE docDate > (SELECT MAX(docDate) FROM T3)
GROUP BY docdate

Hier muss man nicht so stark schachtel. Es langt einfach das letzte Datum abzufragen. Hier siehst du ach den Grund für die Inizialisierung. Ohne einen Datensatz in T2 oder T3 werden keine Daten eingetragen weil die innere SELECT ohne eine Datensatz NULL zurückgeben würde.

Zuletzt noch das DELETE für T1 mit dem Daten älter 2 Tage gelöscht werden. Solte erst nach den beiden INSERTS laufen.


Code:
DELETE FROM T1 WHERE docDate < getdate() - 2

ACHTUNG: nach dem DELETE sind die Daten weg! Also auf Kopie oder mit Spieldaten testen.

Ich hoffe das hat dir weitergeholfen.

Ist mal wieder ein haufen Zeug geworden :)

Gruß Charly
 
Werbung:

Softi

Benutzer
Beiträge
19
AW: Verdichtung von Daten

Hallo Charly,

vielen vielen DANK!!!:)

Echt super von DIR!

Werde die ganze Sache so bald als möglich testen.

Ich wünsche euch allen noch nen schönen Abend,
und hoffe das ich auch bald mal meinen
Beitrag zum Forum leisten kann;)
 
Oben