www.mikrocontroller.net

Forum: PC-Programmierung Kennt sich jemand mit MySQL aus? Komplizierte Abfrage.


Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe folgende Abfrage in einem PHP-Skript, die seit einem Update des 
MySQL-Servers durch meinen Hosting-Anbieter nicht mehr funktioniert:

SELECT
  mitglied.titel as titel,
  mitglied.vorname as vorname,
  mitglied.zusatz as zusatz,
  mitglied.nachname as nachname,
  mitglied.spitzname as spitzname,
  mitglied.id as mid
FROM
  mitglied
WHERE
  (mitglied.nachname like '%$search%' OR
   mitglied.vorname like '%$search%' OR
   mitglied.spitzname like '%$search%') AND
   (SELECT
      mitglied_status.status
    FROM
      mitglied, mitglied_status
    WHERE
     mitglied.id = mitglied_status.mitglied AND
     mitglied_status.mitglied = mid
    ORDER BY
     mitglied_status.datum DESC
    LIMIT 1) IN ($status)
ORDER BY
  mitglied.nachname,
  mitglied.vorname ASC

Im Prinzip sucht die Abfrage alle Mitglieder aus einer Tabelle, deren 
Mitgliedsstatus in $status enthalten ist und deren Nachname, Vorname 
oder Spitzname den Substring $search enthält.

Da ein Mitglied mehrere Mitglieds-Statusse haben kann (1:n-Beziehung), 
sind Mitglieder und Statusse über eine extra Tabelle verknüpft, diese 
nennt sich mitglied_status.

Das Problem dieser verschachtelten Abfrage ist nun, daß das Feld "mid" 
in der inneren Abfrage nicht mehr bekannt ist. Ich muß irgendwie die 
Mitglieds-ID aus der Hauptabfrage in der Nebenabfrage zur Verfügung 
haben. In der alten Version von MySQL ging das problemlos, die Abfrage 
hat so funktioniert. Wie macht man das jetzt vernünftig?

Autor: Michael Appelt (micha54)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Du musst den beiden Tabellen mitglied jeweils einen Alias gebe, also

select a.titel, a..... from mitglied a

....(select b.....from mitglieg b
     where .... = a.id

Kenne aber eher Oracle und MS-Sql....

Gruss,
Michael

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hoffe es ist kein Fehler drin, und ich habe nichts übersehen

SELECT distinct
  m.titel as titel,
  m.vorname as vorname,
  m.zusatz as zusatz,
  m.nachname as nachname,
  m.spitzname as spitzname,
  m.id as mid
FROM
  mitglied m
  join mitglied_status s
     on s.mitglied = m.mid
WHERE
  (mitglied.nachname like '%$search%' OR
   mitglied.vorname like '%$search%' OR
   mitglied.spitzname like '%$search%')
   and s.Status in ( $status )
ORDER BY
  mitglied.nachname,
  mitglied.vorname ASC

Autor: Gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch beiden...

Leider geht's so nicht. Das Problem ist folgendes:

Tabelle Mitglied:

1, Hans, Wurst, Würstchen, ...
2, Gertrude, Heckenpenner, Trudchen, ...

Dann die Tabelle mit der Zuordnung Mitglieds-Status zu Mitglied, wobei 
die komplette Historie mit abgespeichert ist, die das Mitglied je hatte. 
Abgespeichert ist der Primärschlüssel von Mitglied (Mitgliedsnummer), 
der Primärschlüssel vom Status (Status-ID) und das Datum, ab wann das 
Mitglied diesen Status hatte.

Also für Status 1 = Juniormitglied, 2 = Seniormitglied, 3 = 
Fördermitglied könnte die Tabelle so aussehen:

Tabelle mitglied_status:

1, 2, 27.12.2005
1, 3, 01.09.2007
2, 1, 24.04.1971
2, 2, 20.03.1982

Ich brauche jetzt bei meiner Abfrage den aktullen Status des Mitglieds. 
Deshalb die innere Abfrage, wo ich absteigend nach Datum sortiere und 
die Anzahl der Einträge auf 1 limitiere. So kriege ich den letzten 
Eintrag für das betreffende Mitglied, also den aktuellen Status des 
Mitglieds.

Wollte ich jetzt Seniormitglieder suchen, deren Spitzname "chen" 
enthält, würde ich also das Trudchen aus dem o.g. Beispiel finden, nicht 
aber Würstchen, denn der war zwar mal Seniormitglied, ist jetzt aber nur 
noch Fördermitglied.

Gar nicht so einfach. Ich brauche das aber möglichst in EINER Abfrage 
und vor allem kann ich leider an der Datenbankstruktur nichts ändern, 
weil auch andere Programme auf die Datensätze zugreifen.

Danke!

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut jetzt habe ich das Problem verstanden (denke ich). 2.Versuch:

SELECT distinct
  m.titel as titel,
  m.vorname as vorname,
  m.zusatz as zusatz,
  m.nachname as nachname,
  m.spitzname as spitzname,
  m.id as mid
FROM
  mitglied m
  join mitglied_status s
     on s.mitglied = m.mid
  join ( select
             mitglied,
             max(Datum) as Datum
          from
             mitglied_status
          group by mitglied
        ) s2
      on s2.mitglied = m.mitglied
      and s.Datum = s2.Datum
WHERE
  (mitglied.nachname like '%$search%' OR
   mitglied.vorname like '%$search%' OR
   mitglied.spitzname like '%$search%')
   and s.Status in ( $status )
ORDER BY
  mitglied.nachname,
  mitglied.vorname ASC

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.