mySQL MIN(datum)-Problem
verona
- datenbank
Hallo liebes Forum,
ich habe ein kleines Problem mit der Auswertung meiner Datenbank. Ich habe z.B. eine monatliche Abfrage von Terminen.
Im Detail frage ich wie folgt ab...
SELECT datum
FROM termine
WHERE (datum BETWEEN '2003-03-01' AND '2003-03-31')
Gesetzt den Fall, ich habe vier Termine im März, dann erhalte ich auch alle vier Termine. Bis hier ist es alles problemlos. So, jetzt möchte ich aber den jeweils ersten Termin haben.
SELECT MIN(datum)
FROM termine
WHERE (datum BETWEEN '2003-03-01' AND '2003-03-31')
Jetzt erhalte ich nur das jüngste Datum. Auch OK.
Ich brauche aber das jüngste Datum überhaupt, und nicht das jüngsten aus dem März. Wenn z.B. der jüngste Termin im Januar liegt, dann möchte ich eine leere Liste für März angezeigt bekommen. Wie kann ich das machen?
Die folgende Zeile
WHERE (MIN(datum) BETWEEN '2003-03-01' AND '2003-03-31')
liefert mir einen SQL-Fehler.
Danke im voraus V
Halihallo verona
Ich brauche aber das jüngste Datum überhaupt, und nicht das jüngsten aus dem März. Wenn z.B. der jüngste Termin im Januar liegt, dann möchte ich eine leere Liste für März angezeigt bekommen. Wie kann ich das machen?
Mit MySQL<4.1 nur über eine programmiertechnische Lösung.
WHERE (MIN(datum) BETWEEN '2003-03-01' AND '2003-03-31')
liefert mir einen SQL-Fehler.
Zurecht. Was du bräuchtest sind Subqueries (in MySQL>4.2 implementiert).
Viele Grüsse
Philipp
Hi verona, Phillip
Ich brauche aber das jüngste Datum überhaupt, und nicht das jüngsten aus dem März. Wenn z.B. der jüngste Termin im Januar liegt, dann möchte ich eine leere Liste für März angezeigt bekommen. Wie kann ich das machen?
WHERE (MIN(datum) BETWEEN '2003-03-01' AND '2003-03-31')
liefert mir einen SQL-Fehler.
Zurecht. Was du bräuchtest sind Subqueries (in MySQL>4.2 implementiert).
Ne, nur nicht immer so kompliziert, ein bisschen Magie mit Having tuts auch *g*.
select min(datum) as dat
from tabelle
having dat between '2003-03-01' and '2003-03-31'
Du holst dir erst das kleinste Datum, und dann filterst du das Ergebnis auf März oder was immer. Der Unterschied zwischen Having und Where kommt hier zum tragen, Having wird erst aufgeführt, nachdem das Zwischenresultat, also das min(datum) bekannt ist.
http://aktuell.de.selfhtml.org/tippstricks/datenbanken/having/index.htm
Gruss Daniela
Halihallo Daniela
Ne, nur nicht immer so kompliziert, ein bisschen Magie mit Having tuts auch *g*.
Ja, ja :-)
select min(datum) as dat
from tabelle
having dat between '2003-03-01' and '2003-03-31'Du holst dir erst das kleinste Datum, und dann filterst du das Ergebnis auf März oder was immer. Der Unterschied zwischen Having und Where kommt hier zum tragen, Having wird erst aufgeführt, nachdem das Zwischenresultat, also das min(datum) bekannt ist.
Jaja, um ein "erlaubtes" min(datum) zu kriegen, funktioniert das schon, aber du kannst
nicht alle Datensätze im März ausgeben und dieses Ausgeben von der Bedingung (minimales
Datum grösser-gleich Between-Anfang) abhängig machen. Das ist eine "IF-Abfrage" und
lässt sich _nur_ mit Subqueries abbilden. [1]
[1] Hmmmmm... Oder hab ich da doch was übersehen? - Ich geh mal kurz nach draussen an
die frische Schweizer-Luft und überlege nochmals :-)
Viele Grüsse
Philipp
Hi Phillipp
Jaja, um ein "erlaubtes" min(datum) zu kriegen, funktioniert das schon, aber du kannst
nicht alle Datensätze im März ausgeben und dieses Ausgeben von der Bedingung (minimales
Datum grösser-gleich Between-Anfang) abhängig machen. Das ist eine "IF-Abfrage" und
lässt sich _nur_ mit Subqueries abbilden. [1]
Das wollte sie doch aber gar nicht?
Gruss Daniela
Halihallo Daniela
Das wollte sie doch aber gar nicht?
Ich glaube schon:
"Ich brauche aber das jüngste Datum überhaupt, und nicht das jüngsten aus dem März. Wenn z.B. der jüngste Termin im Januar liegt, dann möchte ich eine leere Liste für März angezeigt bekommen. Wie kann ich das machen?"
SELECT a.*, min(b.datum) AS condition
FROM
tabelle AS a,
tabelle AS b
GROUP BY
a.primary_key
HAVING a.datum BETWEEN '2003-03-01' AND '2003-03-31' AND
'2003-03-01' <= condition
Mei, wie konnte ich das übersehen? ;)
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Viele Grüsse
Philipp
Hallo zusammen!
Mei, wie konnte ich das übersehen? ;)
Das brauchst Du gar nicht, denn:
select min(datum) as dat
from tabelle
having dat between '2003-03-01' and '2003-03-31'
und wenn die Abfrage halt zunächts ein Datum im Januar findet, wird das so zu sagen durch Having wieder verworfen, man bekommt also eine "leere Tabelle" zurück.
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Hier reicht schon ein guter Programmierer ;-))))))
Grüße
Andreas
Hi Andreas
und wenn die Abfrage halt zunächts ein Datum im Januar findet, wird das so zu sagen durch Having wieder verworfen, man bekommt also eine "leere Tabelle" zurück.
Ja, genau dass war auch die Aufgabenstellung. Wie willst du dieses Verhalten sonst ohne Subqueries implementieren? Also gib mir das kleinste Datum zurück, falls es in dem und dem Monat liegt.
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Hier reicht schon ein guter Programmierer ;-))))))
Ja, braucht es. Wenn du richtig hinsehen würdest, würdest du sehen, dass genau dies das erwartete verhalten ist, entweder das kleinste Datum ausgeben falls es im entsprechenden Monat ist, oder aber gar nichts zurückgeben. Die Query ist durchaus so wie ich die Frage verstanden habe, und auch optimal so.
Zudem solltest du doch etwas genauer schauen was du zitierst und was welchen Zusammenhang hatte.
Gruss Daniela
Halihallo Daniela
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Hier reicht schon ein guter Programmierer ;-))))))Ja, braucht es. Wenn du richtig hinsehen würdest, würdest du sehen, dass genau dies das erwartete verhalten ist, entweder das kleinste Datum ausgeben falls es im entsprechenden Monat ist, oder aber gar nichts zurückgeben. Die Query ist durchaus so wie ich die Frage verstanden habe, und auch optimal so.
Jo, bei nur Datumsselektion ist er bestimmt optimal und wenn er dann auch der
ursprünglichen Frage entspricht noch besser. Dann habe ich eben die Frage nicht
verstanden ;)
Zudem solltest du doch etwas genauer schauen was du zitierst und was welchen Zusammenhang hatte.
Das sagst du zu mir, oder? - Lass den armen Andreas aus'm Spiel ;)
Viele Grüsse
Philipp
Halihallo Andreas
Mei, wie konnte ich das übersehen? ;)
Das brauchst Du gar nicht, denn:
[...]
und wenn die Abfrage halt zunächts ein Datum im Januar findet, wird das so zu sagen durch Having wieder verworfen, man bekommt also eine "leere Tabelle" zurück.
Ja, ja, ja, ich w-e-i-s-s, ich weiss schon, was der Query bedeutet, nur glaubte ich,
dass dies eben nicht das war, was verona beabsichtigte :-)
Also, ich wollte ein Query vorschlagen, der alle Termine (alle Daten des Termins)
zwischen foo und bar ausgibt, aber _nur dann_, wenn es eben keine früheren Thermine gab.
Also:
if (keine Thermine vor foo) {
SELECT alle-daten from tabelle WHERE datum BETWEEN foo AND bar
} else {
SELECT ABSTRACT EmptySet
}
Wichtig:
Es sollen eben _alle_ daten ausgegeben werden (also auch Name, LastActualized,
Alarm, ...).
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Hier reicht schon ein guter Programmierer ;-))))))
Oho, unerlaubter Tiefschlag, Andreas!! :-))
Viele Grüsse
Philipp
Hi!
Ja, ja, ja, ich w-e-i-s-s, ich weiss schon, was der Query bedeutet, nur glaubte ich,
dass dies eben nicht das war, was verona beabsichtigte :-)
ah so ;-)
Also, ich wollte ein Query vorschlagen, der alle Termine (alle Daten des Termins)
zwischen foo und bar ausgibt, aber _nur dann_, wenn es eben keine früheren Thermine gab.
IMHO war die Frage aber, den ersten Termin auszugeben, falls er in dem Zeitraum liegt, und eben das würde Danielas Query machen wenn ich nicht irre. Was ich da jetzt falsch gemacht habe weiß ich leider nicht.
Hoffentlich arbeitet der QueryOptimizer gut, sonst geht da höllisch Performance verloren.
Hier reicht schon ein guter Programmierer ;-))))))Oho, unerlaubter Tiefschlag, Andreas!! :-))
Ich durfte ja auch schon einstecken, jetzt bin ich mal dran mit austeilen ;-)
Viele Grüße
Andreas
PS: Wie ist eigentlich Dein Semester gelaufen? Hattest Du überhaupt Zeit für Klausuren?
Halihallo Andreas
Also, ich wollte ein Query vorschlagen, der alle Termine (alle Daten des Termins)
zwischen foo und bar ausgibt, aber _nur dann_, wenn es eben keine früheren Thermine gab.
IMHO war die Frage aber, den ersten Termin auszugeben, falls er in dem Zeitraum liegt, und eben das würde Danielas Query machen wenn ich nicht irre. Was ich da jetzt falsch gemacht habe weiß ich leider nicht.
Daniela und Du gar nix. Ich war im Irrglauben, dass sie eben alle Daten dieses ersten
Termins ausgeben wollte, das kompliziert die Sache dann eben ein wenig ;-)
Ja, sogar so stark, dass ich erst mit Subselect abgewunken habe, weil jede andere
Lösung einfach inoptimal (zumindest unschön, aber evtl. eben auch Auswirkungen auf
Performance hätte) ist.
PS: Wie ist eigentlich Dein Semester gelaufen? Hattest Du überhaupt Zeit für Klausuren?
Naja, zeitlich hat's für die Klausur grad noch gereicht, das lernen musste einfach
darunter leiden, was dann auch mit einer 2.3 bestraft wurde :-)
Ansonsten lief es ganz gut, ich habe ja nur eine Vorlesung besucht "Information
Management", war ganz "lustig". Zu lernen hatte ich am Ende auch nicht viel, denn das
war grad ne kleine aber nette Einführung in das Sofware Managements und Datenbanken.
Und du? - Wenn's dann mehr wird, sollten wir ggf. auf E-Mail umsteigen ;)
Viele Grüsse
Philipp
Ohja... vielen lieben Dank Philipp und Daniela,
ich hatte ja schon den richtigen Ansatz. :-) Ich hatte auch mal HAVING probiert, habe dann aber im Übereifer übersehen die WHERE-Anweisung zu entfernen. Nach dem Motto doppelt hält besser. LOL
Jetzt ist aber alles feinifeini
Danke