Ermitteln des MAX-Werts für jeden Tag in einem Monat über mehrere Jahre in MySQL

Jason Dunn

Ich habe eine Datenbank voller Wetterdaten ... insbesondere das Datum, die maximale Temperatur, die minimale Temperatur und den täglichen Niederschlag seit mehr als 100 Jahren. Ich versuche, die maximale Temperatur für jeden Tag und das genaue Datum zu ermitteln, an dem sie über die gesamten 100+ Jahre aufgetreten ist.

Mein Tisch ist ähnlich wie unten aufgebaut ...

+-------+------------+------+------+------+
| id    | date       | thi  | tlo  | rain |
+-------+------------+------+------+------+
| 42856 | 2016-01-01 |   49 |   39 | 0.00 |
| 42857 | 2016-01-02 |   51 |   38 | 0.00 |
| 42858 | 2016-01-03 |   60 |   37 | 0.00 |
| 42859 | 2016-01-04 |   54 |   32 | 0.00 |
| 42860 | 2016-01-05 |   47 |   32 | 0.00 |
+-------+------------+------+------+------+
5 rows in set (0.01 sec)

Ich möchte das Maximum (thi) für jeden Tag des Jahres und das Datum finden, an dem es aufgetreten ist. Diese Daten stammen aus dem Jahr 1899, daher befinden sich für jedes Jahr 117 Januar in der Datenbank und so weiter.

Ich habe mir bisher Folgendes ausgedacht ...

select date, max(thi),
-> DAY(date)
-> from dfw where MONTH(date)='01'
-> group by DAY(date);
+------------+----------+-----------+
| date       | max(thi) | DAY(date) |
+------------+----------+-----------+
| 1899-01-01 |       83 |         1 |
| 1899-01-02 |       78 |         2 |
| 1899-01-03 |       84 |         3 |
| 1899-01-04 |       81 |         4 |
| 1899-01-05 |       82 |         5 |
| 1899-01-06 |       79 |         6 |
| 1899-01-07 |       83 |         7 |
| 1899-01-08 |       88 |         8 |
| 1899-01-09 |       82 |         9 |
| 1899-01-10 |       79 |        10 |
| 1899-01-11 |       83 |        11 |
| 1899-01-12 |       82 |        12 |
| 1899-01-13 |       78 |        13 |
| 1899-01-14 |       79 |        14 |
| 1899-01-15 |       80 |        15 |
| 1899-01-16 |       81 |        16 |
| 1899-01-17 |       79 |        17 |
| 1899-01-18 |       80 |        18 |
| 1899-01-19 |       84 |        19 |
| 1899-01-20 |       83 |        20 |
| 1899-01-21 |       79 |        21 |
| 1899-01-22 |       85 |        22 |
| 1899-01-23 |       88 |        23 |
| 1899-01-24 |       82 |        24 |
| 1899-01-25 |       84 |        25 |
| 1899-01-26 |       82 |        26 |
| 1899-01-27 |       81 |        27 |
| 1899-01-28 |       85 |        28 |
| 1899-01-29 |       84 |        29 |
| 1899-01-30 |       86 |        30 |
| 1899-01-31 |       93 |        31 |
+------------+----------+-----------+
31 rows in set (0.01 sec)

Dies gibt mir das Maximum für jeden Tag im Januar, was gut ist ... aber ich brauche das Datum, an dem es aufgetreten ist. Aus irgendeinem Grund bekomme ich nur 1899.

Zum Beispiel am 31. Januar ... das Maximum (thi) ist 93, aber es ist am 1911-01-31 aufgetreten. Es gibt auch Zeiten, in denen das Maximum (thi) in mehreren Jahren aufgetreten sein könnte. Am 30. Januar ... ist das Maximum (thi) 86, das am 30.01.1906 und am 30.01.1994 aufgetreten ist.

Gibt es eine Möglichkeit, dies in MySQL zu tun, oder habe ich einfach kein Glück? Danke im Voraus!

spencer7593

Der datein Ihrem SELECT für den Ausdruck zurückgegebene Wert ist unbestimmt. MySQL kann einen dateWert aus jeder Zeile in der Gruppe zurückgeben. (Andere Datenbanken würden bei dieser Abfrage einen Fehler auslösen. Eine MySQL-spezifische Erweiterung von GROUP BY ermöglicht die Ausführung der Abfrage, aber wir können MySQL dazu bringen, sich besser an den SQL-Standard anzupassen, und bei dieser Abfrage einen Fehler auslösen, indem wir ONLY_FULL_GROUP_BY einschließen sql_mode.)

Du hast einen guten Start.

          SELECT DATE_FORMAT(n.date,'%m%d') AS mmdd 
               , MAX(n.thi) AS max_thi
            FROM dfw
           GROUP BY DATE_FORMAT(n.date,'%m%d')   

Um das Jahr zu bekommen, gibt es ein paar Ansätze. Eine besteht darin, die Abfrage als Inline-Ansicht zu verwenden und mit der ursprünglichen Tabelle zu verknüpfen, um eine passende Zeile mit demselben Monat und Tag und demselben Wert zu finden.

Sie können entweder das Aggregat MAX () oder MIN () verwenden, um das späteste oder früheste Datum zu erhalten.

 SELECT m.mmdd
      , m.thi
      , MAX(t.date)  AS latest_date
      , MIN(t.date)  AS earliest_date
   FROM ( 
          SELECT DATE_FORMAT(n.date,'%m%d') AS mmdd 
               , MAX(n.thi) AS thi
            FROM dfw
           GROUP BY DATE_FORMAT(n.date,'%m%d')   
        ) m
  JOIN dfw t
    ON t.thi                      = m.thi
   AND DATE_FORMAT(t.date,'%m%d') = m.mmdd  
 GROUP BY m.mmdd
 ORDER BY m.mmdd

Wenn Sie alle Jahre für eine bestimmte mmdd zurückgeben möchten, bei der der höchste Wert aufgetreten ist, entfernen Sie die GROUP BY-Klausel und das Aggregat von ungefähr t.date

 SELECT m.mmdd
      , m.thi
      , t.date
   FROM ( 
          SELECT DATE_FORMAT(n.date,'%m%d') AS mmdd 
               , MAX(n.thi) AS thi
            FROM dfw
           GROUP BY DATE_FORMAT(n.date,'%m%d')   
        ) m
  JOIN dfw t
    ON t.thi                      = m.thi
   AND DATE_FORMAT(t.date,'%m%d') = m.mmdd  
 ORDER BY m.mmdd, t.date

Als weitere Alternative können Sie eine korrelierte Unterabfrage in der SELECT-Liste verwenden, um das früheste Datum zu ermitteln, an dem dies aufgetreten ist:

 SELECT DATE_FORMAT(n.date,'%m%d') AS mmdd 
      , MAX(n.thi) AS thi
      , ( SELECT t.date
            FROM dfw t
           WHERE DATE_FORMAT(t.date,'%m%d') = DATE_FORMAT(n.date,'%m%d')
             AND t.thi = n.thi
           ORDER BY t.date 
           LIMIT 0,1
        ) AS earliest_date 
   FROM dfw n
  GROUP BY DATE_FORMAT(n.date,'%m%d')   
  ORDER BY DATE_FORMAT(n.date,'%m%d')   

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

TOP Liste

heißlabel

Archiv