1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Hilfe MIN()

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von smacksmash, 16 Februar 2020.

  1. smacksmash

    smacksmash Neuer Benutzer

    Hallo,
    ich bin blutiger Anfänger was SQL betrifft und habe ein Problem wo ich nicht weiterkomme.
    Ich habe eine Tabelle mit 2 Spalten DatumZeit (datetime) und Temp (double). Es existiert für jede Minute ein Temp-Wert.

    Ich möchte mir für jeden der letzten 7 Tage die minimale Temperatur mit Zeitangabe ausgeben und nutze dafür folgenden Code:

    SELECT DATE_FORMAT(DatumZeit,'%d.%m.%Y') AS DATUM, DATE_FORMAT(DatumZeit,'%H:%i') AS ZEIT, MIN(Temp) AS TEMP_MIN
    FROM messwerte_temp_s1
    WHERE `datumzeit` >= date_sub(now(), interval 7 day) AND `datumzeit` <= now()
    GROUP BY DATE_FORMAT(DatumZeit,'%d.%m.%Y ')
    ORDER BY DatumZeit $Sortierung

    Leider liefert mir das ganze zwar den niedrigsten Temp-Wert des Tages, aber leider ohne dazugehörige Zeit.
    Über Hilfe wäre ich dankbar!
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Das SQL ist syntaktisch falsch, was MySQL aber nicht merkt und statt einem Fehler irgend was ausliefert. Merke: Alle Spalten im Resultset müssen entweger aggregiert oder gruppiert sein. Du hast 3 Spalten im Resultat, davon 1 Aggregation. Von den 2 anderen Spalten ist nur nach einer gruppiert.
     
  3. smacksmash

    smacksmash Neuer Benutzer

    Danke für deine Antwort.
    Gruppiere ich beide Spalten

    GROUP BYDATE_FORMAT(DatumZeit,'%d.%m.%Y'), DATE_FORMAT(DatumZeit,'%H:%i')

    bekomme ich alle Temp-Werte ausgegeben, ohne das diese nach den minimalsten gefiltert sind.
     
  4. akretschmer

    akretschmer Datenbank-Guru

    viele Wege führen nach Rom:

    Code:
    test=*# create table m(ts timestamp, wert int);
    CREATE TABLE
    test=*# insert into m select current_date + s * '10hour'::interval, random()*20 from generate_series(1,20)s;
    INSERT 0 20
    test=*# select * from m;
             ts          | wert
    ---------------------+------
     2020-02-16 10:00:00 |    6
     2020-02-16 20:00:00 |    5
     2020-02-17 06:00:00 |    5
     2020-02-17 16:00:00 |   14
     2020-02-18 02:00:00 |   12
     2020-02-18 12:00:00 |    5
     2020-02-18 22:00:00 |   11
     2020-02-19 08:00:00 |    5
     2020-02-19 18:00:00 |   14
     2020-02-20 04:00:00 |   20
     2020-02-20 14:00:00 |    6
     2020-02-21 00:00:00 |    4
     2020-02-21 10:00:00 |   15
     2020-02-21 20:00:00 |    7
     2020-02-22 06:00:00 |   19
     2020-02-22 16:00:00 |   12
     2020-02-23 02:00:00 |   18
     2020-02-23 12:00:00 |    2
     2020-02-23 22:00:00 |   17
     2020-02-24 08:00:00 |   17
    (20 rows)
    test=*# with x as (select ts, wert, rank() over (partition by ts::date order by wert) from m) select ts, wert from x where rank = 1 order by ts;
             ts          | wert
    ---------------------+------
     2020-02-16 20:00:00 |    5
     2020-02-17 06:00:00 |    5
     2020-02-18 12:00:00 |    5
     2020-02-19 08:00:00 |    5
     2020-02-20 14:00:00 |    6
     2020-02-21 00:00:00 |    4
     2020-02-22 16:00:00 |   12
     2020-02-23 12:00:00 |    2
     2020-02-24 08:00:00 |   17
    (9 rows)
    test=*# select ts, wert from m where (ts::date, wert) in (select ts::date, min(wert) from m group by ts::date order by ts::date);
             ts          | wert
    ---------------------+------
     2020-02-16 20:00:00 |    5
     2020-02-17 06:00:00 |    5
     2020-02-18 12:00:00 |    5
     2020-02-19 08:00:00 |    5
     2020-02-20 14:00:00 |    6
     2020-02-21 00:00:00 |    4
     2020-02-22 16:00:00 |   12
     2020-02-23 12:00:00 |    2
     2020-02-24 08:00:00 |   17
    (9 rows)
    
    MySQL kann aber manche Dinge nicht ...
     
  5. smacksmash

    smacksmash Neuer Benutzer

    Ich habe versucht das Ganze zu testen. Leider ohne Erfolg.
    Ist diese Syntax über MySQL möglich ?
     
  6. akretschmer

    akretschmer Datenbank-Guru

    die letztere Version sollte gehen, evtl. als JOIN umschreiben.

    Code:
    test=*# select m.* from m inner join (select ts::date, min(wert) from m group by ts::date) x on m.ts::date=x.ts::date and m.wert=x.min order by ts;
             ts          | wert
    ---------------------+------
     2020-02-16 20:00:00 |    5
     2020-02-17 06:00:00 |    5
     2020-02-18 12:00:00 |    5
     2020-02-19 08:00:00 |    5
     2020-02-20 14:00:00 |    6
     2020-02-21 00:00:00 |    4
     2020-02-22 16:00:00 |   12
     2020-02-23 12:00:00 |    2
     2020-02-24 08:00:00 |   17
    (9 rows)
    
    Oder halt gleich eine richtige DB verwenden, die logische Fehler erkennt und die seit 20 Jahren üblichen Features beherrscht. Also im Prinzip alles außer MySQL.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden