This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
sql:tutorials:selectrecordwithmaxdatepergroup [20.04.2015 10:13:53] yaslaw mysql:tutorials:selectrecordwithmaxdatepergroup renamed to sql:tutorials:selectrecordwithmaxdatepergroup |
sql:tutorials:selectrecordwithmaxdatepergroup [17.10.2019 14:10:04] (current) yaslaw [Ausgangslage] |
||
---|---|---|---|
Line 2: | Line 2: | ||
Einige Beispiele wie man pro Gruppe die Zeile mit dem neusten Datum ermitteln kann. | Einige Beispiele wie man pro Gruppe die Zeile mit dem neusten Datum ermitteln kann. | ||
- | Komplexere DBMS besitzen Analytische Funktionen, die so was abnehmen. Nicht aber <nowiki>MySQL</nowiki>. Ergo muss hier auf diese | + | Komplexere DBMS besitzen Analytische Funktionen, die so was abnehmen. Nicht aber <nowiki>MySQL und MS Access</nowiki>. Ergo muss hier auf diese |
Funktionen verzichtet werden. | Funktionen verzichtet werden. | ||
=====Ausgangslage===== | =====Ausgangslage===== | ||
- | Als Beispiel nehme ich eine einfache Währungskurs-Tabelle. Sie hat pro Währungs-kombination mehrere Einträge. nun mächte ich von jeder Kombination den aktuellsten Eintrag auslesen | + | Als Beispiel nehme ich eine einfache Währungskurs-Tabelle. Sie hat pro Währungs-kombination mehrere Einträge. nun möchte ich von jeder Kombination den aktuellsten Eintrag auslesen |
<code>[kurs] | <code>[kurs] | ||
w1 | w2 | kurs | datum | w1 | w2 | kurs | datum | ||
Line 18: | Line 18: | ||
=====Lösungsansatz===== | =====Lösungsansatz===== | ||
Dazu müssen wir erst einmal für jede Währungskombination das aktuellste Datum auslesen | Dazu müssen wir erst einmal für jede Währungskombination das aktuellste Datum auslesen | ||
- | <code sql>SELECT w1, | + | <code sql>SELECT w1, w2, MAX(datum) AS max_datum |
- | w2, | + | FROM kurs |
- | MAX(datum) AS max_datum | + | GROUP BY w1, w2;</code> |
- | FROM kurs | + | |
- | GROUP BY w1, | + | |
- | w2 | + | |
- | ;</code> | + | |
Das ergibt dann die folgende Ausgabe | Das ergibt dann die folgende Ausgabe | ||
<code>w1 | w2 | max_datum | <code>w1 | w2 | max_datum | ||
Line 46: | Line 42: | ||
Das Subquery wird mittels WHERE-Beziehungen an die Daten geknüpft | Das Subquery wird mittels WHERE-Beziehungen an die Daten geknüpft | ||
- | <code sql>SELECT | + | <code sql>SELECT k.* |
- | k.* | + | |
FROM | FROM | ||
- | kurs AS k, | + | kurs AS k, |
- | ( | + | ( |
- | SELECT | + | SELECT w1, w2, MAX(datum) AS max_datum |
- | w1, | + | FROM kurs |
- | w2, | + | GROUP BY w1, w2 |
- | MAX(datum) AS max_datum | + | ) AS le |
- | FROM | + | |
- | kurs | + | |
- | GROUP BY | + | |
- | w1, | + | |
- | w2 | + | |
- | ) AS le | + | |
WHERE | WHERE | ||
- | k.w1 = le.w1 | + | k.w1 = le.w1 |
- | AND k.w2 = le.w2 | + | AND k.w2 = le.w2 |
- | AND k.datum = le.max_datum;</code> | + | AND k.datum = le.max_datum;</code> |
Line 71: | Line 60: | ||
Dasselbe wie zuvor, einfach mit der INNER-JOIN-Schreibweise | Dasselbe wie zuvor, einfach mit der INNER-JOIN-Schreibweise | ||
- | <code sql>SELECT | + | <code sql>SELECT k.* |
- | k.* | + | |
FROM | FROM | ||
kurs AS k | kurs AS k | ||
INNER JOIN ( | INNER JOIN ( | ||
- | SELECT w1, | + | SELECT w1, w2, MAX(datum) AS max_datum |
- | w2, | + | FROM kurs |
- | MAX(datum) AS max_datum | + | GROUP BY w1, w2 |
- | FROM kurs | + | ) AS le |
- | GROUP BY w1, | + | |
- | w2 | + | |
- | ) AS le --Last_entries | + | |
ON | ON | ||
k.w1 = le.w1 | k.w1 = le.w1 | ||
Line 93: | Line 78: | ||
Natürlich kann man das auch mit IN() im WHERE-Bereich erledigen | Natürlich kann man das auch mit IN() im WHERE-Bereich erledigen | ||
- | <code sql>SELECT | + | <code sql>SELECT k.* |
- | k.* | + | FROM kurs AS k |
- | FROM | + | |
- | kurs AS k | + | |
WHERE | WHERE | ||
(k.w1, k.w2, k.datum) IN ( | (k.w1, k.w2, k.datum) IN ( | ||
- | SELECT w1, | + | SELECT w1, w2, MAX(datum) AS max_datum |
- | w2, | + | FROM kurs |
- | MAX(datum) AS max_datum | + | GROUP BY w1, w2 |
- | FROM kurs | + | );</code> |
- | GROUP BY w1, | + | |
- | w2 | + | |
- | ) | + | |
- | ;</code> | + | |
Line 113: | Line 92: | ||
oder als Korrelierte Unterabfrage | oder als Korrelierte Unterabfrage | ||
- | <code sql>SELECT | + | <code sql>SELECT k.* |
- | k.* | + | FROM kurs AS k |
- | FROM | + | |
- | kurs AS k | + | |
WHERE | WHERE | ||
k.datum IN ( | k.datum IN ( | ||
- | SELECT MAX(datum) AS max_datum | + | SELECT MAX(datum) AS max_datum |
- | FROM kurs | + | FROM kurs |
- | WHERE kurs.w1 = k.w1 | + | WHERE kurs.w1 = k.w1 AND kurs.w2 = k.w2 |
- | AND kurs.w2 = k.w2 | + | GROUP BY w1, w2 |
- | GROUP BY w1, | + | );</code> |
- | w2 | + | |
- | ) | + | ==== Mittels DMAX() in MS Access ==== |
+ | ''MS Access'' | ||
+ | |||
+ | In MS Access kann man auch mit DMAX() arbeiten. Mit DMAX() das aktuelleste Datum auslesen und im WHERE verknüpfen | ||
+ | <code sql>SELECT k.* | ||
+ | FROM kurs AS k | ||
+ | WHERE k.datum = DMAX("datum", "kurs", "[w1]='" & k.w1 & "' AND [w2]='" & k.w2 & "'") | ||
;</code> | ;</code> | ||
Line 131: | Line 114: | ||
Nehmen wir an, wir wollen nun wissen, was der Kurs am 19ten war | Nehmen wir an, wir wollen nun wissen, was der Kurs am 19ten war | ||
- | Wir können einfach im inneren Query noch die Bedinung mit dem Datum hinzufügen. Also Datum der Tabelle ist kleiner oder gleich dem Selektionierten Datum. | + | Wir können einfach im inneren Query (Abfragedes aktuellen Datums) noch die Bedinung mit dem Datum hinzufügen. Also Datum der Tabelle ist kleiner oder gleich dem Selektionierten Datum. |
- | > Der Datumstring ist je nach DBMS. Oracle: TO_DATE('19.03.2011', 'DD.MM.YYYY'), Access: #03-11-2015# | + | > Der Datumstring ist je nach DBMS. Oracle: TO_DATE('19.03.2011', 'DD.MM.YYYY'), Access: #03/19/2011# |
- | <code sql>SELECT w1, | + | <code sql>SELECT w1, w2, MAX(datum) AS max_datum |
- | w2, | + | FROM kurs |
- | MAX(datum) AS max_datum | + | WHERE datum <= 2011-03-19 |
- | FROM kurs | + | GROUP BY w1, w2 |
- | WHERE datum <= 2011-03-19 | + | |
- | GROUP BY w1, | + | |
- | w2 | + | |
;</code> | ;</code> | ||
+ | |||
+ | Oder beim DMAX-Beispiel im Access: | ||
+ | <code sql>WHERE k.datum = DMAX("datum", "kurs", "[w1]='" & k.w1 & "' AND [w2]='" & k.w2 & "' AND [datum] <= #03/19/2011#")</code> | ||