none
foreach und Array Ersatz wie umsetzen RRS feed

  • Frage

  • Hallo für einen Report suche ich einen Ansatz für eine Lösung und komme einfach nicht weiter.

    Ich habe eine Abfrage die mir für einen bestimmten Zeitbereich ID´s ermittelt, mit diesen wieder rum kann ich in einer anderen Tabelle weitere Abfragen machen. Das ganze realisiere ich, in dem ich diverse Variablen deklariere und diese dann alle in einer Tabelle ausgebe.

    Das klappt für eine ID auch super. Jedoch wie kann ich es bewerkstelligen für mehr als eine gefundene ID?

    in anderen Sprachen würde ich das Ergebnis der ID´s in eine Array speichern und mit einer foreach Schleife die ganze Prozedur so oft durchlaufen, bis ich alle ID´s aus dem Arrray abgearbeitet habe.

    Jedoch gibt es im SQL Server Version 2008 kein Array. wie kann ich das denn sonst lösen?

    Mittwoch, 4. Mai 2016 03:06

Antworten

  • Meinst Du so etwas?

    create table #timestamps (
    ID int null,
    timestamp_start datetime,
    timestamp_ende datetime);
    
    create table #produktionsdaten
    ( 
    station1 int null,
    station2 int null,
    Zeit datetime null);
    
    insert into #timestamps values (403, '05/04/2016 9:00','05/04/2016 9:05') ;
    insert into #timestamps values (404, '05/04/2016 9:06','05/04/2016 10:00'); 
    
    insert into #produktionsdaten values (1000, 2000, '05/04/2016 9:00');
    insert into #produktionsdaten values (1000, 3000, '05/04/2016 9:10');
    insert into #produktionsdaten values (1000, 4000, '05/04/2016 9:20');
    insert into #produktionsdaten values (1000, 5000, '05/04/2016 9:30');
    
    With Vorberechnung as
    (Select ID, timestamp_start, timestamp_ende
    from #timestamps
    )
    SELECT ID, V.timestamp_start, V.timestamp_ende, sum(station1) as Sum_1, sum (station2) as Sum_2
    FROM #produktionsdaten AS T1
    INNER JOIN Vorberechnung as V
    	on T1.Zeit between V.timestamp_start and V.timestamp_ende
    group by ID, V.timestamp_start, V.timestamp_ende 
    ;
    go
    
    drop table #timestamps;
    drop table #produktionsdaten;


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Montag, 9. Mai 2016 07:45
    Beantworter

Alle Antworten

  • Hallo,

    Du hast aber doch etwas ähnliches. Du kannst Werte in einer temporären Tabelle speichern.

    Und bei Abfragen hast Du ja die Joins und kannst sehr viel machen. Zur Not (!!) gibt  es auch noch Cursor, mit denen Du über die Ergebnisse eine Abfrage gehen kannst. Aber wirklich erst schauen, ob es nicht doch anders geht.

    So kannst Du ja auch Dinge in einer Query aufrufen und berechnen lassen. Das ist um ein vielfaches besser als die Verwendung eines Cursors.

    Wenn Du genauere Details liefern kannst, dann könnte man Dir evtl. auch dabei helfen, entsprechende Queries aufzubauen.

    Viele Grüße,

    Konrad

    Mittwoch, 4. Mai 2016 03:26
  • Hallo,

    wie Konrad schon schrieb, sollte man bei Datenbanken keine iterativen Lösungen suchen, sondern immer Set-Based. Eine Möglichkeit ist, die beiden Abfragen über einen JOIN zu verbinden, das ist das performanteste. Andere Möglichkeit ist z.B. ein IN Abfrage nach der Art:

    SELECT T1.*
    FROM Tabelle1 AS T1
    WHERE T1.Id IN
        (SELECT T2.Id
         FROM Tabelle2 AS T2
         WHERE Datum BETWEEN ... AND ...)


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Mittwoch, 4. Mai 2016 11:27
  • ich versuche es noch mal etwas genauer zu erklären. aus einer Tabelle hole ich mir für einen bestimmten Tag einen Timestamp_Start und Timestamp_Stop (Produktionsbeginn und Produktionsende). Meist sind es mehrere Produktionen somit gibt es auch mehrere Timestamp_Start und Timestamp_Sop

    Das bedeutet ich habe folgendes Ergebnis

    ID Timestamp_Start Timestamp_Stop

    403  5.5.2016 16:20 5.5.2016 16:30

    404 5.5.2016 18:00  5.5.2016  18:30

    Jetzt müsste ich in die Produktionsdaten reinschauen und je nach Vorgabe die Werte berechnen. Die Produktionsdaten werden jede Minute in die Datenbank geschrieben.

    Das heißt es muss nun in einer anderen Tabelle (produktionsdaten) geschaut werden und über between die Daten ermittelt werden.

    zb. Select  sum(station1), sum (station2)  from produktionsdaten where (Timestamp between 5.5.2016 16:20 and 5.5.2016 16:30). Jedoch wie bekomme ich die ID 404 rein? irgendwie stehe ich total auf dem Schlauch!   


    Donnerstag, 5. Mai 2016 14:20
  • create table timestamps (
    ID int null,
    timestamp_start datetime,
    timestamp_ende datetime)
    go
    
    create table produktionsdaten
    ( 
    ID int null,
    station1 int null,
    station2 int null,
    Zeit datetime null)
    go
    
    
    insert into timestamps values (403, '05/04/2016 9:00','05/04/2016 9:00') 
    insert into timestamps values (403, '05/04/2016 9:01','05/04/2016 10:00') 
    insert into timestamps values (404, '05/04/2016 9:00','05/04/2016 10:00') 
    insert into timestamps values (404, '05/05/2016 9:00','05/05/2016 10:00') 
    
    select * from timestamps
    
    insert into produktionsdaten values (404, 1000,1000, '05/04/2016 9:00')
    
    insert into produktionsdaten values (404, 1000,1000, '05/04/2016 9:10')
    
    insert into produktionsdaten values (404, 1000,1000, '05/04/2016 9:20')
    
    insert into produktionsdaten values (403, 1000,1000, '05/04/2016 9:00')
    
    SELECT id, sum(station1), sum (station2)
    FROM produktionsdaten AS T1
    WHERE T1.Id IN
        (SELECT T2.Id
         FROM timestamps AS T2
         WHERE zeit BETWEEN '05/04/2016 9:00' AND '05/04/2016 9:20')
    group by id
    
    SELECT id, sum(station1), sum (station2)
    FROM produktionsdaten AS T1
    WHERE ID = 404 and T1.Id IN
        (SELECT T2.Id
         FROM timestamps AS T2
         WHERE zeit BETWEEN '05/04/2016 9:00' AND '05/04/2016 9:20')
    group by id

    Hier zwei Varianten für deine Abfrage


    Benjamin Hoch
    MCSE: Data Platform
    MCSA: Windows Server 2012
    Blog

    Donnerstag, 5. Mai 2016 15:50
  • Hallo Benjamin. Die Idee ist nicht schlecht jedoch liegt das Problem darin das die zweite Tabelle keine ID hat.

    Das heißt es müsste so etwas in der Art abgefragt werden.

    SELECT

    TimeStamp_Start,ID,TimeStamp_Stop FROM [SKEMS-HST].[dbo].[Produktionszeiten]

    WHERE (TimeStamp_Start Between CONVERT(datetime,'2016-04-23 00:00:00.000', 121)

    and CONVERT(datetime,'2016-04-23 23:59:59.000' , 121)) as T1


    WHERE

    T1.TimeStamp_Start AND T1.TimeStamp_Stop IN


    (SELECT T2.Bias


    FROM  [SKEMS-HST].[dbo].[Trend009] AS T2


    WHERE Time_Stamp BETWEEN T1.TimeStamp_Start AND T1.TimeStamp_Stop)

    Montag, 9. Mai 2016 07:09
  • Meinst Du so etwas?

    create table #timestamps (
    ID int null,
    timestamp_start datetime,
    timestamp_ende datetime);
    
    create table #produktionsdaten
    ( 
    station1 int null,
    station2 int null,
    Zeit datetime null);
    
    insert into #timestamps values (403, '05/04/2016 9:00','05/04/2016 9:05') ;
    insert into #timestamps values (404, '05/04/2016 9:06','05/04/2016 10:00'); 
    
    insert into #produktionsdaten values (1000, 2000, '05/04/2016 9:00');
    insert into #produktionsdaten values (1000, 3000, '05/04/2016 9:10');
    insert into #produktionsdaten values (1000, 4000, '05/04/2016 9:20');
    insert into #produktionsdaten values (1000, 5000, '05/04/2016 9:30');
    
    With Vorberechnung as
    (Select ID, timestamp_start, timestamp_ende
    from #timestamps
    )
    SELECT ID, V.timestamp_start, V.timestamp_ende, sum(station1) as Sum_1, sum (station2) as Sum_2
    FROM #produktionsdaten AS T1
    INNER JOIN Vorberechnung as V
    	on T1.Zeit between V.timestamp_start and V.timestamp_ende
    group by ID, V.timestamp_start, V.timestamp_ende 
    ;
    go
    
    drop table #timestamps;
    drop table #produktionsdaten;


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Montag, 9. Mai 2016 07:45
    Beantworter
  • Danke Christoph das mit dem With habe ich gesucht! kannte ich nicht das man das so machen kann!

    Aber ich habe noch ein Problem. Ich möchte nun mit mehreren Views und Abfragen im BIDS einen Report erstellen. Nun bin ich aber Crystal Report verwöhnt und weiß noch nicht so recht wie ich alle Datasets mit einander verbinden kann. Der Primärschlüssel wäre nun in allen Tabellen die ID. Das heißt das erste Dataset bestimmt die ID´s und die anderen Datasets sollen mit dem "Parameter" weiterarbeiten. Da das ganze nun aber arg komplex wird möchte ich das gern wie in Crystal Report grafisch lösen. Kann mir jemand helfen?


    Oder kurz gesagt gibt es im BIDS nicht die Möglichkeit die einzelnen Datasets mit einander in Abhängigkeit zu bringen?
    Dienstag, 10. Mai 2016 14:58
  • Am besten machst Du dazu einen neuen Thread auf.

    Was ich gerne in solchen Fällen mache, sind Sub-Reports, die die ID dann als Parameter erhalten.


    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Mittwoch, 11. Mai 2016 09:34
    Beantworter