This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
sql:tutorials:selectrecordwithmaxdatepergroup [09.02.2017 08:57:26] yaslaw [Lösungsansatz] |
sql:tutorials:selectrecordwithmaxdatepergroup [17.10.2019 14:10:04] (current) yaslaw [Ausgangslage] |
||
---|---|---|---|
Line 7: | Line 7: | ||
=====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 42: | 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 67: | 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 89: | 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 109: | 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 | + | |
- | ) | + | |
- | ;</code> | + | |
==== Mittels DMAX() in MS Access ==== | ==== Mittels DMAX() in MS Access ==== | ||
Line 128: | Line 106: | ||
In MS Access kann man auch mit DMAX() arbeiten. Mit DMAX() das aktuelleste Datum auslesen und im WHERE verknüpfen | In MS Access kann man auch mit DMAX() arbeiten. Mit DMAX() das aktuelleste Datum auslesen und im WHERE verknüpfen | ||
- | <code sql>SELECT | + | <code sql>SELECT k.* |
- | k.* | + | FROM kurs AS k |
- | FROM | + | WHERE k.datum = DMAX("datum", "kurs", "[w1]='" & k.w1 & "' AND [w2]='" & k.w2 & "'") |
- | kurs AS k | + | |
- | WHERE | + | |
- | k.datum = DMAX("datum", "kurs", "[w1]=" & k.w1 & " AND [w2]=" & k.w2) | + | |
;</code> | ;</code> | ||
Line 141: | Line 116: | ||
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. | 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/19/2011# | > 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: | Oder beim DMAX-Beispiel im Access: | ||
- | <code sql>WHERE | + | <code sql>WHERE k.datum = DMAX("datum", "kurs", "[w1]='" & k.w1 & "' AND [w2]='" & k.w2 & "' AND [datum] <= #03/19/2011#")</code> |
- | k.datum = DMAX("datum", "kurs", "[w1]=" & k.w1 & " AND [w2]=" & k.w2 & " AND [datum] <= #03/19/2011#")</code> | + | |