none
Abfrage Min/Max Wert und zugehöriges Datum RRS feed

  • Frage

  • Hallo Forum,

    mit der Google Recherche komme ich nicht weiter.

    Ich habe folgende Tabelle:    id - dt - Itemname - Value

    Gespeichert wird alle Minute ein Wert. Als Wert kann auch die 0 vorkommen .

    Als ausgabe möchte ich vom Tag das Min(Value) den Max(Value) mit dem entsprechedem dt Wert haben.

    Die Selektion auf tag und ausgabe der min/max Werte bekomm ich hin.

    Wie stelle ich es an, das mir auch der entsprechende dt Wert zu dem Min/MAx angezeigt wird?

    Gruß

    Frank

    Montag, 11. Januar 2016 12:43

Antworten

  • Hallo Frank,

    so als ersten Wurf würde ich mal das hier in den Raum schmeißen.

    WITH Query AS
    (
    SELECT   Tagname,
             MIN( Value ) AS MinValue,
             MAX( Value ) AS MaxValue
    FROM     Messwerte
    GROUP BY Tagname
    ), MinValuesQuery AS
    (
    SELECT   m.Tagname,
             q.MinValue,
             MIN( dt ) AS MinDt
    FROM     Messwerte m
             INNER JOIN Query q ON m.Tagname = q.Tagname AND m.Value = q.MinValue
    GROUP BY m.Tagname,
             q.MinValue
    ), MaxValuesQuery AS
    (
    SELECT   m.Tagname,
             q.MaxValue,
             MAX( dt ) AS MaxDt
    FROM     Messwerte m
             INNER JOIN Query q ON m.Tagname = q.Tagname AND m.Value = q.MaxValue
    GROUP BY m.Tagname,
             q.MaxValue
    )
    SELECT minvq.Tagname,
           minvq.MinValue,
           minvq.MinDt,
           maxvq.MaxValue,
           maxvq.MaxDt
    FROM   MinValuesQuery minvq
           CROSS JOIN MaxValuesQuery maxvq
    WHERE  minvq.Tagname = maxvq.Tagname

    Ist aber sicher noch verbesserungswürdig.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Montag, 11. Januar 2016 16:39
    Moderator

Alle Antworten

  • Hallo Frank,

    SELECT   dt,
             MIN( Value ) AS MinValue,
             MAX( Value ) AS MaxValue
    FROM     Tabelle
    GROUP BY dt



    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Montag, 11. Januar 2016 12:50
    Moderator
  • Hallo Stefan,

    danke für die schnelle Antwort ABER die Abfrage liefert nicht das was ich haben möchte.

    Ich möchte zu dem Min bzw. zu dem Max Wert den Zeitpunkt (dt) ausgeben.

    Erste Abfrage liefert Mittelwert / Minimum / Maximum,
    zweite Abfrage liefert das was Du geschreiben hast.

    Temp Tabelle gefüllt
    Tagname                                                                          Mittel                 Minimum                Maximum
    -------------------------------------------------------------------------------- ---------------------- ---------------------- ----------------------
    ST03_ISTWERT01.value                                                             31.5170103092783       29.62                  33
    ST03_ISTWERT02.value                                                             0                      0                      0
    ST03_ISTWERT03.value                                                             0.172164948453609      0.16                   0.18
    ST03_ISTWERT04.value                                                             0                      0                      0

    (4 row(s) affected)

    dt                      Tagname                                                                                                 
    ----------------------- -------------------------------------------------------------------------------- ---------------------- ----------------------
    2015-11-06 09:41:00.000 ST03_ISTWERT01.value                                                             31.62                  31.62
    2015-11-06 09:42:00.000 ST03_ISTWERT01.value                                                             31.25                  31.25
    2015-11-06 09:43:00.000 ST03_ISTWERT01.value                                                             31.37                  31.37
    2015-11-06 09:44:00.000 ST03_ISTWERT01.value                                                             31.37                  31.37
    2015-11-06 09:45:00.000 ST03_ISTWERT01.value                                                             31.12                  31.12

    Montag, 11. Januar 2016 13:16
  • Hallo Frank,

    Du musst "nur" die Gruppierung an Deine Wünsche anpassen, z. B. um einen Wert je Tag zu erhalten:

    SELECT   CAST(dt AS Date) AS Datum,
             MIN( Value ) AS MinValue,
             MAX( Value ) AS MaxValue
    FROM     Tabelle
    GROUP BY CAST(dt AS Date)
    
    

    wobei hier der CAST auf den Date Datentyp der einfachste Weg ist. Beim anderen Zeiträumen wird es etwas komplexer.

    Gruß Elmar

    Montag, 11. Januar 2016 13:23
    Beantworter
  • Hallo Elmar,
    "nur" ist gut. :-(
    Mit Cast gehts nicht. In meiner Tabelle sind schon nur die Tagesdaten enthalten.

    Nun soll "nur" noch zu dem min bzw. max wert die Uhrzeit ausgegeben werden.
    Mache ich cast(dt as time) erhalte ich alle Minutenwerte zurück.

    Das passt noch nicht!

    Wie muß denn diese Abfrage lauten ?

    Gruß

    Frank

    Montag, 11. Januar 2016 13:52
  • Oder meinst Du so etwas?

    With CTE_MAX as
    (
    SELECT     CAST(dt AS Date) AS Datum_Max,
                    Value as Value_Max,
                    ROW_NUMBER() OVER(ORDER BY Value desc) as rn_max
    FROM         Tabelle
    ),
    CTE_MIN as
    (
    SELECT     CAST(dt AS Date) AS Datum_Min,
                    Value as Value_Min,
                    ROW_NUMBER() OVER(ORDER BY Value) as rn_min
    FROM         Tabelle
    )
    Select Datum_Max, Value_Max, Datum_Min, Value_Min
    from CTE_MAX, CTE_MIN
    where rn_max = 1
    and rn_min = 1;
    

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

    Montag, 11. Januar 2016 13:55
  • Hallo Christoph,

    ja fast. Jetzt bekomme ich aus allen Datensätzen das Maximum.

    Was nicht drin ist, das für jeden Tagnamen das min / max ausgegeben wird.

    Also "nur" noch für jeden Tagnamen das min /max.

    Gruß

    Frank

    Montag, 11. Januar 2016 14:03
  • Hallo Frank,

    bitte schau Dir mal die Grundlagen zu Datum und Zeit an:

    Datums- und Uhrzeitdatentypen und zugehörige Funktionen (Transact-SQL)

    (die meisten Funktionen existieren ab SQL Server 2008 - ggf Version auswählen).

    Um ein Datum zu verkürzen (bis zur Stunde / Minute / Sekunde) braucht es etwas Arithmetik. Der Stackoverflow-Artikel zeigt es exemplarisch ohne Sekunden - gilt aber für alle anderen äquivalent:

    http://stackoverflow.com/questions/8896663/a-way-to-extract-from-a-datetime-value-data-without-seconds

    Gruß Elmar

    Montag, 11. Januar 2016 14:49
    Beantworter
  • Hallo Frank,

    wieso jetzt auf einmal "Tagname"?

    Poste bitte deine Tabellenstruktur als CREATE TABLE Statement, deine Beispieldaten als INSERT INTO Statement(s) und passend zu den Beispieldaten nochmal (bitte so formatiert, dass es lesbar ist) die gewünschten Ergebniszeilen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Montag, 11. Januar 2016 14:49
    Moderator
  • Hallo Stefan,

    vielleicht habe ich es nicht richtig umschrieben.
    In der Tabelle sind für diverse Meßstellen Minutenwerte gespeichert.
    Ziel ist es zu jeder Meßstelle den Tages Min und Tages Max Wert mit der Uhrzeit auszulesen.

    Die Abfrage um den Tages Min und Max Wert zu jeder Meßstelle zu bekommen habe ich. Nur mit der Abfrage der Uhrzeit bzw. des datetime Feldes, da weiß ich nicht weiter.

    -- Tabelle Messwerte CREATE TABLE [dbo].[Messwerte]( [id] [int] IDENTITY(0,1) NOT NULL, [dt] [datetime] NOT NULL, [Tagname] [varchar](80) NOT NULL, [Value] [float] NULL ) ON [PRIMARY]


    INSERT INTO [dbo].[Messwerte]
               ([dt]
               ,[Tagname]
               ,[Value] )
    VALUES
    ( 2015-11-06 09:41:00.000, ST03_ISTWERT01.value, 31.62 )
    ( 2015-11-06 09:42:00.000, ST03_ISTWERT01.value, 32.62 )
    ( 2015-11-06 09:43:00.000, ST03_ISTWERT01.value, 33.62 )
    ( 2015-11-06 09:44:00.000, ST03_ISTWERT01.value, 11.62 )
    ( 2015-11-06 09:45:00.000, ST03_ISTWERT01.value, 0.0 )
    ( 2015-11-06 09:46:00.000, ST03_ISTWERT01.value, 5.0 )
    ( 2015-11-06 09:41:00.000, ST01_ISTWERT01.value, 31.62 )
    ( 2015-11-06 09:42:00.000, ST01_ISTWERT01.value, 32.62 )
    ( 2015-11-06 09:43:00.000, ST01_ISTWERT01.value, 33.62 )
    ( 2015-11-06 09:44:00.000, ST01_ISTWERT01.value, 11.62 )
    ( 2015-11-06 09:45:00.000, ST01_ISTWERT01.value, 0.0 )
    ( 2015-11-06 09:46:00.000, ST01_ISTWERT01.value, 5.0 )
    go
    

    --So stelle ich mir die Abfrage vor

    SELECT Tagname, MIN(Value) as Minimum, dt as MinZeit, MAX(Value) as Maximum, dt as maxZeit FROM Tabelle ORDER BY Tagname

    Gruß

    Frank

    Montag, 11. Januar 2016 15:21
  • Hallo Frank,

    so als ersten Wurf würde ich mal das hier in den Raum schmeißen.

    WITH Query AS
    (
    SELECT   Tagname,
             MIN( Value ) AS MinValue,
             MAX( Value ) AS MaxValue
    FROM     Messwerte
    GROUP BY Tagname
    ), MinValuesQuery AS
    (
    SELECT   m.Tagname,
             q.MinValue,
             MIN( dt ) AS MinDt
    FROM     Messwerte m
             INNER JOIN Query q ON m.Tagname = q.Tagname AND m.Value = q.MinValue
    GROUP BY m.Tagname,
             q.MinValue
    ), MaxValuesQuery AS
    (
    SELECT   m.Tagname,
             q.MaxValue,
             MAX( dt ) AS MaxDt
    FROM     Messwerte m
             INNER JOIN Query q ON m.Tagname = q.Tagname AND m.Value = q.MaxValue
    GROUP BY m.Tagname,
             q.MaxValue
    )
    SELECT minvq.Tagname,
           minvq.MinValue,
           minvq.MinDt,
           maxvq.MaxValue,
           maxvq.MaxDt
    FROM   MinValuesQuery minvq
           CROSS JOIN MaxValuesQuery maxvq
    WHERE  minvq.Tagname = maxvq.Tagname

    Ist aber sicher noch verbesserungswürdig.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Montag, 11. Januar 2016 16:39
    Moderator
  • Hallo Stefan,

    danke, das funktioniert, es werden die Ergebnisse geliefert welche ich suche.

    Gruß

    Frank

    Montag, 11. Januar 2016 17:02