SQL Dynamische Zuweisung von Wert aus zweiter Tabelle

jb_alvarado

Lieutenant
Registriert
Sep. 2015
Beiträge
594
Hallo Allerseits,
irgendwie komme ich hier gerade nicht weiter...

Ich habe zwei Tabellen:
  1. Mitglieder (mit Adressdaten)
  2. Gruppe (Kinder, Singles, Familienstand, Senioren)
Jetzt hätte ich gerne eine Abfrage, die die Mitglieder mit jeweiliger Gruppe verbindet. Das Ergebnis sollte dann in etwas so aussehen:

NameAdresseGeburtstagFamilienstandGruppe
MaxGrüner Platz 7, 12345 Sonstwo01.01.1950VerheiratetSenioren
LisaRote Allee 5, 67890 Nirgendwo02.03.2018LedigKinder

Das es Überschneidungen geben kann, vernachlässigen wir mal in diesem Beispiel...

Wie kann ich das in mySQL abbilden?
 
Dachte ich auch zuerst aber wenn ich z.B. das mache:

SQL:
SELECT *, Gruppe.Name FROM Mitglieder
INNER JOIN Gruppe ON (TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) <= '5')

Kommt nichts vernünftiges bei raus.
Ergänzung ()

Habe jetzt was hinbekommen:

SQL:
SELECT *,
IF(TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) <= '16',
   (SELECT Name FROM Gruppe WHERE ID = 1),
   IF(TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) >= '65',
     (SELECT Name FROM Gruppe WHERE ID = 3), '')
  ) AS Gruppe FROM Liste

So in etwa müsste es gehen.
 
Zuletzt bearbeitet:
Wie sehen denn die Tabellen aus? Ich seh da grad nirgends IDs...

Dann einen Join on Mitglied.gID = Gruppe.ID und schon paßt das.

So wie du’s hast könnte man für Mitglied eine berechnete Spalte bauen, zb per View, sodaß sich Mitglied.gID aus den Daten ergibt. Nicht so schön, aber geht. Dann diese gID für den join.

Dafür zB case when. Etwas sauberer und vor allem übersichtlicher.
 
  • Gefällt mir
Reaktionen: jb_alvarado
RalphS schrieb:
Wie sehen denn die Tabellen aus? Ich seh da grad nirgends IDs...

Dann einen Join on Mitglied.gID = Gruppe.ID und schon paßt das.
Normalerweise würde ich das so auch machen, aber in diesem Fall brauche ich das dynamisch. Das ganze ist ja zeit- und zustandsabhängig. Und das möchte ich nicht jedes Jahr, oder bei jeder Familienstandänderung händisch anpassen müssen.

RalphS schrieb:
So wie du’s hast könnte man für Mitglied eine berechnete Spalte bauen, zb per View, sodaß sich Mitglied.gID aus den Daten ergibt. Nicht so schön, aber geht. Dann diese gID für den join.

Dafür zB case when. Etwas sauberer und vor allem übersichtlicher.

Das war ein guter Hinweis! Views in mySQL habe ich nicht so gerne, weil ich die Erfahrung gemacht habe. dass die bei einem Datenbank Dump nicht richtig mitgespeichert werden. Allerdings habe ich jetzt was andere gefunden, nämlich "Generated Columns" (hast du von denen gesprochen?), die kannte ich noch nicht und sind echt eine feine Sache. So kann ich zumindest schon mal das Alter in eine eigen Spalte schreiben, und brauche das nicht jedes mal in die Abfrage mit rein schreiben.

Würdest du jetzt noch eine weitere Generated Columns anlegen, für die Mitglieder.gID? Aber was meinst du dann noch mit der case when Bedingung?
 
jb_alvarado schrieb:
Normalerweise würde ich das so auch machen, aber in diesem Fall brauche ich das dynamisch. Das ganze ist ja zeit- und zustandsabhängig. Und das möchte ich nicht jedes Jahr, oder bei jeder Familienstandänderung händisch anpassen müssen.
Ich glaube, du hast da was grundsätzlich nicht verstanden.
 
Du kannst auch CASE-Statements in den Join-Bedingungen verwenden.
Damit könntest du das auch ohne View abbilden:
SQL:
select *, Gruppe.Name
from Mitglieder
inner join Gruppe on (Gruppe.ID = case
                                  when TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) <= '5'
                                    then 0
                                  when TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) between '6' and '16'
                                    then 1
                                  when TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) between '16' and '21'
                                    then 2
                                  when TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) between '21' and '65'
                                    then 3
                                  /*usw.*/
                                  end)
Ich weiß nicht, wie und ob MySQL da die Strings passend mit between vergleichen kann.
U.U. musst du entweder das Ergebnis von TIMESTAMPDIFF in einen Integer umwandeln oder die WHEN-Klauseln erweitern, sodass die Grenzen einzeln mit dem Ergebnis von TIMESTAMPDIFF verglichen werden.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Ah das meine @RalphS mit case when. Danke für den Tip!

Das ist auch übersichtlicher als meine IF-Verschachtelung. Ich denke, ich werde das kombinieren mit den Generated Columns.

@Fombu: wenn das so ist, erkläre bitte den Fragestellern auch warum, damit man auch was lernen kann.
 
Hat jemand Lust, mir die Modellierung zu erklären? Willst du die Gruppe nicht anhand einer Referenz in deiner Mitglieder-Tabelle ranjoinen, sondern über ihr Alter zum Zeitpunkt der Abfrage? Was hält denn deine Gruppe sonst noch außer etwas scheinbar Enum-Wertigen? Brauchst du diese Gruppen-Tabelle oder interessiert dich die Gruppenzuordnung eigentlich nur als transientes Attribut, gebildet aus deinen Zeitintervallen?
 
Eine weiter Idee wäre, dass Du die Altersgrenzen in der Gruppentabelle ablegst.
GruppeIdBezeichnungAlterMinAlterMax
1Kinder05

und dann die Abfrage darüber machst

SQL:
select m.*, g.Bezeichnung
  from Mitglieder m
    join Gruppen g
      on TIMESTAMPDIFF(YEAR, Geburtstag, CURDATE()) between g.AlterMin and g.AlterMax

Das hat den Vorteil, dass Du problemlos die Gruppengrenzen ändern kannst oder neue Gruppen einfügen kannst und die Abfrage dafür nicht ändern musst.
 
  • Gefällt mir
Reaktionen: norbert_pdm, Oelepoeto und floq0r
Danke @AgiOli für den Vorschlag. Grundsätzlich gefällt mir das, aber ich denke das ist in meinem Fall etwas unhandlicher. Die Gruppen definieren sich nicht nur über Alter, sondern auch über Familienstand (Alleinstehend, Verheiratet). Ein Alleinstehender unter einem gewissen Alter würde dabei in die Gruppe Jugend kommen, und ab 65 in die Gruppe Senioren.

Das ganze verwalte ich in LibreOffice Base, daher kann ich dort in den Abfragen recht schnell auch Änderungen vornehmen.

@mental.dIseASe, ich hoffe ich verstehe dich richtig: ich möchte die Gruppentabelle separat behalten und nur per Abfrage an das Ergebnis anfügen. Das soll dann immer zum Zeitpunkt des Abfragens aktualisiert werden.

Auch habe ich noch eine Gruppenleiter Tabelle, denen auch die Gruppe, die sie Verwalten, zugeteilt werden soll.
 
Wenn du zu der Gruppe noch mehr Sachen wie den Gruppenleiter hast, dann ist das sinnvoll. Schau, dass du es umsetzt wie von @AgiOli vorgeschlagen. Das ist ziemlich elegant.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Ich weiß nicht, ob du (TE) dich mit Normalformen auskennst, schau mal, ob du deine Tabellen so weit runterbrechen kannst, dass du nur atomare Werte hast.
Dann kannst du natürlich zu jeder beliebigen Zeit eine (aktuelle) Abfrage über alles mögliche generieren.
 
  • Gefällt mir
Reaktionen: jb_alvarado
Zurück
Oben