Dennis: mehrere Datensätze mit Versionsnummern - Übersicht holen

Hallo liebes Forum ;-)

Gerade arbeite ich an einem System, welches die Vertretungspläne an meiner Schule verwalten können soll. Dazu gibt es in der MySQL Datenbank (Version 4.1, läuft auf Debian) eine Tabelle, welche für jeden vorhandenen Plan einen Eintrag enthält, das ganze sieht so aus:

id    |   datum    |  version
 Prim. Key |   DATE     |   INT 2
-----------+------------+-----------
        1  | 2006-03-27 |        1
        2  | 2006-03-27 |        2
        3  | 2006-03-28 |        1
        4  | 2006-03-29 |        1
        5  | 2006-03-30 |        1
        6  | 2006-03-30 |        2

Es gibt also immer einen Eintrag mit Versionsnummer 1, es kann aber beliebig viele weitere Einträge geben mit steigender Versionsnummer.

In einer zweiten Tabelle sind dann die Daten für die Pläne abgelegt - zu Zuordnung erfolgt über die ID des Planes, soviel nur am Rande.

Mit folgendem SQL Befehl hole ich mir den aktuellsten Plan für ein Datum:

SELECT id FROM tabelle WHERE datum = '2006-03-27' ORDER BY version DESC LIMIT 1

Das klappt auch einwandfrei - doch jetzt soll eine Übersicht erstellt werden, in der für jedes in der Datenbank vorhandene Datum ein Plan angezeigt werden soll, jedoch (logischerweise) immer nur der aktuellste, also der mit der höchsten Versionsnummer.

Wie kann ich das am geschicktesten lösen? Geht das überhaupt in einer SQL Abfrage?

So spontan fällt mir nur eine Sache ein: Per GROUP BY datum alle vorhandenen Datum auslesen und dann für jedes Datum einzeln einen SQL Query absetzen (wie oben). Doch geht es auch einfacher?

MfG, Dennis.

  1. Hallo Dennis,

    Dazu gibt es in der MySQL Datenbank (Version 4.1,

    das ist die wichtigste Information - und eine gute dazu.

    doch jetzt soll eine Übersicht erstellt werden, in der für jedes in der Datenbank vorhandene Datum ein Plan angezeigt werden soll, jedoch (logischerweise) immer nur der aktuellste, also der mit der höchsten Versionsnummer.

    Wie kann ich das am geschicktesten lösen? Geht das überhaupt in einer SQL Abfrage?

    ja.

    So spontan fällt mir nur eine Sache ein: Per GROUP BY datum alle vorhandenen Datum auslesen und dann für jedes Datum einzeln einen SQL Query absetzen (wie oben). Doch geht es auch einfacher?

    Grausam, aber vor MySQL 4.1 nur mit einem ganz schmutzigen Trick zu lösen.

    Dies ist eine häufig gestellte Frage. Diese Frage habe ich zuletzt heute um 13:45 Uhr beantwortet.

    GROUP BY mit SUBSELECT löst Dein Problem auf elegante Weise.

    Freundliche Grüße

    Vinzenz

    1. Hi Vinzenz,

      Dies ist eine häufig gestellte Frage. Diese Frage habe ich zuletzt heute um 13:45 Uhr beantwortet.

      Nach dem ich eine Weile gebraucht habe um es zu verstehen, hat mir die verlinkte Seite gut weitergeholfen - vielen Dank dafür. Allerdings möchte ich zur Rettung meiner Ehre noch sagen, dass ich nie auf die Idee gekommen wäre unter dem Begriff „The Rows Holding the Group-wise Maximum of a Certain Field“ nach einer Lösung des Problems zu suchen ;-)

      GROUP BY mit SUBSELECT löst Dein Problem auf elegante Weise.

      Ich habe es jetzt so gelöst:

      SELECT  
        felder  
      FROM  
        tabelle tb1  
      WHERE  
        version = (SELECT MAX(version)  
                   FROM tabelle tb2  
                   WHERE tb1.day = tb2.day)  
      ORDER BY  
        day ASC
      

      Allerdings verstehe ich das „tabelle tb1“ noch nicht ganz - was passiert da genau? Ich kenne eigentlich nur „FROM tabelle AS alias“...

      Gerade mal geguckt - das Manual sagt dazu: „A table reference can be aliased using tbl_name AS alias_name or tbl_name alias_name“ - es besteht also kein Unterschied und ich könnte genauso tabelle AS tb1 schreiben?

      Vielen Dank dir für deine Mühen,

      MfG, Dennis.

      1. Hi,

        Gerade mal geguckt - das Manual sagt dazu: „A table reference can be aliased using tbl_name AS alias_name or tbl_name alias_name“ - es besteht also kein Unterschied und ich könnte genauso tabelle AS tb1 schreiben?

        ja, das ist eine generell akzeptierte Kurzschreibweise, ich glaube (bitte nicht hauen) sie steht sogar als Vorschrift im SQL-Standard.

        MfG
        Rouven

        --
        -------------------
        ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
        1. Hi Rouven,

          ja, das ist eine generell akzeptierte Kurzschreibweise, ich glaube (bitte nicht hauen) sie steht sogar als Vorschrift im SQL-Standard.

          Ok, vielen Dank :-)

          MfG, Dennis.

  2. Hi !

    id    |   datum    |  version
    Prim. Key |   DATE     |   INT 2
    -----------+------------+-----------
            1  | 2006-03-27 |        1
            2  | 2006-03-27 |        2
            3  | 2006-03-28 |        1
            4  | 2006-03-29 |        1
            5  | 2006-03-30 |        1
            6  | 2006-03-30 |        2

    select plan from plantabelle a, obige_tabelle b where a.id=b.id and (datum,version) in (select datum, max(version) from obige_tabelle c group by datum);

    Gruß

    Hans

    1. Hi Hans,

      select plan from plantabelle a, obige_tabelle b where a.id=b.id and (datum,version) in (select datum, max(version) from obige_tabelle c group by datum);

      Damit würde ich die Inhalts-Daten der Pläne bekommen, ja - aber ich habe mich wohl offensichtlich etwas mißverständlich ausgedrückt: Ich wollte gar nicht an die Inhalte der Pläne, sondern nur die Übersicht über alle vorhandenen Pläne, dabei jedoch nicht mehr aktuelle Versionen auslassen. Dank Vinzenzs Hilfe hat es jetzt geklappt.

      MfG, Dennis.