TomTom: MySQL: SELECT-Abfrage mit JOINS und MAX()

Hi,

ich habe die folgenden Tabellen (die fuer die Abfrage relevanten Spalten):

Tabelle: kunden
+-------------+-------------+
| kunden_id   | kunden_name |
+-------------+-------------+
| 1           | kunde-1     |
| 2           | kunde-2     |
| 3           | kunde-3     |
| 4           | kunde-4     |
| 5           | kunde-5     |
+-------------+-------------+

Tabelle: objekte
+-------------+-------------+-------------+
| objekt_id   | kunden_id   | objekt_name |
+-------------+-------------+-------------+
| 1           | 1           | objekt-1    |
| 2           | 2           | objekt-2    |
| 3           | 3           | objekt-3    |
| 4           | 4           | objekt-4    |
| 5           | 4           | objekt-5    |
| 6           | 4           | objekt-6    |
+-------------+-------------+-------------+

Tabelle: objekt_notizen
+---------------------+-------------+-----------+-----------+
| objekt_notizen_id   | objekt_id   | notiz     | aktiv     |
+---------------------+-------------+-----------+-----------+
| 1                   | 1           | notiz-1-1 | Y         |
| 2                   | 1           | notiz-1-2 | N         |
| 3                   | 1           | notiz-1-3 | Y         |
| 4                   | 1           | notiz-1-4 | Y         |
| 5                   | 2           | notiz-2-1 | Y         |
| 6                   | 2           | notiz-2-2 | Y         |
| 7                   | 4           | notiz-4-1 | Y         |
| 8                   | 4           | notiz-4-2 | Y         |
| 9                   | 5           | notiz-5-1 | Y         |
| 10                  | 6           | notiz-6-1 | Y         |
+---------------------+-------------+-----------+-----------+

Tabelle: services
+--------------+-------------+--------------+---------------+
| service_id   | objekt_id   | service_text | service_datum |
+--------------+-------------+--------------+---------------+
| 1            | 1           | service-1    | 2007-10-10    |
| 2            | 2           | service-2    | 2007-10-11    |
| 3            | 3           | service-3    | 2007-10-12    |
| 4            | 1           | service-4    | 2008-02-01    |
| 5            | 2           | service-5    | 2008-02-02    |
| 6            | 3           | service-6    | 2008-02-03    |
| 7            | 5           | service-7    | 2008-02-04    |
+--------------+-------------+--------------+---------------+

Ich moechte nun eine ausfuehrliche Gesamtliste der Objekte ausgeben - in der folgenden Form:
Pro Objekt eine Zeile,
alle aktiven Objekt-Notizen sollen aufgelistet werden - objekte.notiz = 'Y',
zusaetzlich soll das letzte Service aufgelistet werden - MAX(service.service_datum).

Es gibt jedoch Kunden ohne Objekte
und Objekte ohne Objekt-Notizen bzw. Objekte mit mehreren aktiven Notizen
sowie Objekte ohne Service-Einsaetze.

Ich scheitere bei den verschachtelten LEFT OUTER JOINS.
Brauche ich eine Unterabfragen um das letzte Service zu erhalten?

+--------------+-------------+----------------+--------------+------------------+
| Kunden       | Objekte     | Objekt-Notizen | Service      | letztes Services |
+--------------+-------------+----------------+--------------+------------------+
| kunde-1      | objekt-1    | notiz-1-1      | Service 4    | 2008-02-01       |
|              |             | notiz-1-3      |              |                  |
|              |             | notiz-1-4      |              |                  |
+--------------+-------------+----------------+--------------+------------------+
| kunde-2      | objekt-2    | notiz-2-1      | Service 5    | 2008-02-02       |
|              |             | notiz-2-2      |              |                  |
+--------------+-------------+----------------+--------------+------------------+
| kunde-3      | objekt-3    |                | Service 6    | 2008-02-03       |
+--------------+-------------+----------------+--------------+------------------+
| kunde-4      | objekt-4    | notiz-4-1      |              |                  |
|              |             | notiz-4-2      |              |                  |
+--------------+-------------+----------------+--------------+------------------+
| kunde-4      | objekt-5    | notiz-5-1      | Service 7    | 2008-02-04       |
+--------------+-------------+----------------+--------------+------------------+
| kunde-4      | objekt-6    | notiz-6-1      |              |                  |
+--------------+-------------+----------------+--------------+------------------+
| kunde-5      |             |                |              |                  |
+--------------+-------------+----------------+--------------+------------------+

Vielen Dank im Voraus fuer Loesungsansaetze und Hilfen,
Tom.

  1. Hallo,

    Ich moechte nun eine ausfuehrliche Gesamtliste der Objekte ausgeben - in der folgenden Form:

    die Ausgabe ist nicht unbedingt Aufgabe einer Abfrage.

    Pro Objekt eine Zeile,

    hmm, hmm. Mehrere Objektnotizen in einer Zeile, dazu kannst Du in MySQL die Aggregatsfunktion GROUP_CONCAT verwenden.

    alle aktiven Objekt-Notizen sollen aufgelistet werden - objekte.notiz = 'Y',
    zusaetzlich soll das letzte Service aufgelistet werden - MAX(service.service_datum).

    Es gibt jedoch Kunden ohne Objekte

    Möchtest Du diese Kunden anzeigen lassen? Wenn nein, wo ist das Problem?
    Wenn ja, wo ist das Problem?

    und Objekte ohne Objekt-Notizen bzw. Objekte mit mehreren aktiven Notizen
    sowie Objekte ohne Service-Einsaetze.

    Ich scheitere bei den verschachtelten LEFT OUTER JOINS.

    Geh' der Reihe nach vor. Joine hübsch eine Tabelle nach der anderen dazu.

    Brauche ich eine Unterabfragen um das letzte Service zu erhalten?

    Ja, eine korrelierte Unterabfrage, die Du mit dem Rest joinst.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      erstmal danke fuer die Tipps!
      GROUP_CONCAT gibt es ab MySQL 4.1 - ich hab hier nur 4.0.12 - da muss ich vorher noch updaten :-(

      Gruss,
      Tom.

      1. echo $begrüßung;

        GROUP_CONCAT gibt es ab MySQL 4.1 - ich hab hier nur 4.0.12 - da muss ich vorher noch updaten :-(

        Unbedingt eine Datensicherung machen, ab Version 4.1 gibt es gravierende Änderungen beim Thema Zeichenkodierung. Es sollte problemlos gehen, auf übliche Weise einen SQL-Dump anzufertigen. Beim Importieren nicht vergessen, anzugeben, dass die Kodierung des Dumps Latin1 ist, denn das wird aufgrund der Default-Konfiguration sicher auch die von dir auf dem 4.0er verwendete sein.

        Der nächste Stolperstein ist der laufende Betrieb und die Kommunikation zwischen den Clients und dem DBMS. Die Kodierung der String-Felder sollte eine passende Kodierung aufweisen, und nach jedem Verbindungsaufbau ist die zu verwendende Kodierung auszuhandeln: mysql_set_character_set() aus der MySQL-Client-API bzw. deren Pendants in den programmiersprachenspezifischen Implementierungen (mysql_set_charset() unter PHP beispielsweise). Als Notlösung geht immerhin noch, ein "SET NAMES"-Statement abzusetzen.

        echo "$verabschiedung $name";