verona: mySQL MIN(datum)-Problem

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

  1. 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

    1. 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

      --
      Nein, wir frieren unsere Hühner nicht auf Gletschern fest.
      Selfcode: sh:) fo:) ch:) rl:) br:> n4:| ie:{ mo:) va:) de:] zu:} fl:( ss:) ls:&
      1. 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

        1. 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

          --
          Nein, wir frieren unsere Hühner nicht auf Gletschern fest.
          Selfcode: sh:) fo:) ch:) rl:) br:> n4:| ie:{ mo:) va:) de:] zu:} fl:( ss:) ls:&
          1. 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

            1. Hallo zusammen!

              Mei, wie konnte ich das übersehen? ;)

              Das brauchst Du gar nicht, denn:

              select min(datum) as dat
                from tabelle

              das selektiert Dir das kleines Datum aus der ganzen Tabelle

              having dat between '2003-03-01' and '2003-03-31'

              und auf dieses Ergebnis wird dann HAVING als Filter angewendet

              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

              1. 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

                --
                Nein, wir frieren unsere Hühner nicht auf Gletschern fest.
                Selfcode: sh:) fo:) ch:) rl:) br:> n4:| ie:{ mo:) va:) de:] zu:} fl:( ss:) ls:&
                1. 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

              2. 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

                1. 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?

                  1. 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

  2. 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