# MySQL: SELECT-Abfrage bei mehreren Werten in einer Spalte



## Tuppie (9. Januar 2021)

Hallo, ich versuche mich gerade an meiner ersten datenbank und habe eine Spalte angelegt, die mehrere Namen beinhaltet (Teilnehmer an einer Sportveranstaltung). Ich habe die Namen in der Spalte mit Komma getrennt:
'Teilnehmer 1, Teilnehmer 2 usw'
Ich würde nun gerne mit einer SELECT-Abfrage nach einzelnen Teilnehmern suchen können, also in etwa so:
SELECT * FROM `veranstaltungen` WHERE Teilnehmer = 'Teilnehmer1'
Leider klappt das aber nicht. Warum? Das müsste sich doch umsetzen lassen. Es sollte auch reichen, nur einen Teilnamen (Vor- oder Nachname) einzugeben... Wie setze ich das um?


----------



## basti1012 (9. Januar 2021)

Tuppie hat gesagt.:


> SELECT * FROM `veranstaltungen` WHERE Teilnehmer = 'Teilnehmer1'


Das würde klappen wenn du nur den einen Namen in der Spalte stehen hast.
Da du aber mehrer Namen in der Spalte hast solltest du mal nach LIKE goggeln.
REGEX könnte auch klappen , doch als Anfänger vieleicht etwas schwer.

Vieviele Datensätze hat deine Tabelle den ?
Falls es zb nur die eine wäre könntest du die Zeile einfach holen und mit Php explode() deine Spalte auseinander nehmen und durchsuchen.


----------



## Sprint (10. Januar 2021)

Vielleicht wäre es auch eine Überlegung wert, ob du die Namen nicht in einzelnen Datensätzen ablegst. Und die Veranstaltungen in einer eigenen Tabelle. Dann könntest du auch zusätzliche Informationen den einzelnen Namen zuweisen, z.B. Zeiten oder Punkte.

Zum Anfang also z.B. eine Tabelle mit Namen und ID (laufende Nummer) der Veranstaltung und eine Tabelle mit Namen, Vornamen, Veranstaltung-ID und einer Teilnehmer-ID (ebenfalls laufende Nummer).

Und beschäftige dich auch mal mit der Normalisierung einer Datenbank. Das ist auch für Anfänger verständlich und es gibt genügend Beispiele dazu. Dann erhöht sich zwar vielleicht die Anzahl der Tabellen und Abfragen können umfangreicher werden, insgesamt aber tust du dich später mal viel leichter, wenn du Daten ändern oder abfragen willst.


----------



## Yaslaw (10. Januar 2021)

Geh noch einen Schritt weiter als Sprint. Das ist ein Klassiker für 3 Tabellen, denn du hast unendlich Teilnehmer die jeweils an unendlich Veranstalltungen teilnehmen können
- Tabelle Personen, mit ID, Name, Vorname etc.
- Tabelle Veranstallungen, mit eigener ID, Name, Ort, Termin etc.
- Tabelle Teilnehmer, mit je iener Zeile mit der ID der Veranstalltung und der ID des Teilnehmers

Diese Lösung findest du auch in jedem Lehrbuch. Von Anfang an sauber auftrennen, damit verbaust du dir nichts. Deine Lösung ist Excel, nicht Datenbank. Du kannst es zwar so lösen wie basti1012 schreibt, jedoch wirst du in Zukunft immer Probleme haben.

Beispiel:

```
TBL_PERSONEN
PID | VORNAME | NACHNAME
  1 | Hans    | Muster
  2 | Lena    | Keller
  3 | Susi    | Müller

TBL_VERANSTALLTUNGEN
VID | EVENT_NAME
  1 | Frühlingsturnier
  2 | Spezialturnier

TBL_TEILNEHMER
PID | VID
  1 | 1
  2 | 1
  2 | 2
  3 | 2
```
SQL-ABfrage mt einem einfachen INNER JOIN

```
SELECT 
    v.* 
FROM 
    TBL_VERANSTALLTUNGEN v,
    TBL_TEILNEHMER t,
    TBL_PERSONEN p
WHERE 
    p.NACHNAME = 'KELLER'
    AND t.PID = p.PID
    AND t.VID = v.VID
```


----------



## Tuppie (10. Januar 2021)

basti1012 hat gesagt.:


> Das würde klappen wenn du nur den einen Namen in der Spalte stehen hast.
> Da du aber mehrer Namen in der Spalte hast solltest du mal nach LIKE goggeln.
> REGEX könnte auch klappen , doch als Anfänger vieleicht etwas schwer.
> 
> ...


Meine Tabelle hat derzeit knapp 100 Datensätze, es werden aber sukzessive mehr...
Mitunter muss ich die Möglichkeit haben, auch an die 30 Teilnehmer pro Veranstaltung eintragen zu können, um dann in allen Datensätzen nach einem bestimmten Teilnehmer suchen zu können...
LIKE / REGEX sagt mir noch nichts, google ich aber mal, danke für den Hinweis!


----------



## basti1012 (10. Januar 2021)

Du solltest aber versuchen den Beitrag 2 oder 3 nachzukommen.
Es vereinfacht dir vieles.
Bedenke das eine LIKE suche nach "Anna", auch bei Hanna positiv ist (Krasses Beispiel).
Oder, alle Spalten holen und später mit explode zu bearbeiten macht bei mehreren 1000 Einträge eine Performance Probleme (Vielleicht auch ein Timeout).
REGEX in Datenbanken zu nutzen ist meiner Meinung nach nicht gerade was für Anfänger. 
Ich habe das mal nach dein Beispiel versucht und nur in der Teilnehmer Spalte nach einem Namen gesucht, mit Ergebnissen die noch nicht zufriedenstellend sind.
REGEX in DB ist er was für Profis.

Hast du den die ,Möglichkeiten  deine Tabellen wie in #2,#3 steht aufzubauen, oder sind die so vorgegeben und nicht mehr änderbar


----------



## Yaslaw (10. Januar 2021)

Wie bast schreibt. Unbedingt aufteilen. Was du hast, ist Excel, aber KEINE DATENBANK. Eine Datenbank besteht aus mehreren zusammenhängenden Tabellen.


----------



## Tuppie (11. Januar 2021)

Lieber Foris,
ich danke Euch sehr für die guten Anregungen, mit denen ich mich in Unkenntnis der Materie noch in Ruhe befassen werde. An dieser Stelle: kennt Ihr hier einen guten Web- oder Buchtipp, man dem man sich diesbezüglich ordentlich einarbeiten kann? 
LIEBEN DANK!


----------



## Tuppie (11. Januar 2021)

Yaslaw hat gesagt.:


> Geh noch einen Schritt weiter als Sprint. Das ist ein Klassiker für 3 Tabellen, denn du hast unendlich Teilnehmer die jeweils an unendlich Veranstalltungen teilnehmen können
> - Tabelle Personen, mit ID, Name, Vorname etc.
> - Tabelle Veranstallungen, mit eigener ID, Name, Ort, Termin etc.
> - Tabelle Teilnehmer, mit je iener Zeile mit der ID der Veranstalltung und der ID des Teilnehmers
> ...


Hallo Yaslaw,
ich verstehe, wie Du da meinst. Was mache ich aber dann, wenn z.B. der Veranstaltungsname ebenfalls aus zwei oder mehr Wörtern bestehen muss, z.B. "Karl Otto Gedächtnisturnier" oder ähnlich? Hier soll man ja hinsichtlich des Veranstaltungsnamens die Möglichkeit haben, nur nach "Karl" oder "Otto" zu suchen...???


----------



## Tuppie (11. Januar 2021)

basti1012 hat gesagt.:


> Hast du den die ,Möglichkeiten  deine Tabellen wie in #2,#3 steht aufzubauen, oder sind die so vorgegeben und nicht mehr änderbar


Ich kann das alles noch umbauen, derzeit bin ich in der Probierphase und merke natürlich jetzt, dass mein derzeitiger Aufbau so nicht zum Ziel führt  Aber besser später als nie merken ;-)


----------



## basti1012 (11. Januar 2021)

Jetzt kannst du aber noch alles ändern und anpassen.
Deswegen gleich richtig machen.
Yaslaw ist dafür der richtige Ansprechpartner.


Tuppie hat gesagt.:


> An dieser Stelle: kennt Ihr hier einen guten Web- oder Buchtipp,


Was in richtig HTML, CSS, Javascript geht, würde ich  HTML-Seminar vorschlagen. Videokurs HTML + CSS auf DVD bestellen
Die haben ein Video Kurs und Online auch viel Input zum Lernen.
Einen Anfänger Kurs für PHP gibt es da auch.
PHP lernen für Anfänger mit Übungen + Videos - PHP-Kurs.com
Da lernst du auch einen Grundkurs wie man mit Datenbank arbeitet.
Willst du aber mehr lernen (z. B. REGEX in Datenbanken usw..), musst du mal weiter rumfragen, ob es dafür ein Buch oder sonst was zugibt, was dir empfohlen wird.


----------



## Zvoni (11. Januar 2021)

Tuppie hat gesagt.:


> Hallo Yaslaw,
> ich verstehe, wie Du da meinst. Was mache ich aber dann, wenn z.B. der Veranstaltungsname ebenfalls aus zwei oder mehr Wörtern bestehen muss, z.B. "Karl Otto Gedächtnisturnier" oder ähnlich? Hier soll man ja hinsichtlich des Veranstaltungsnamens die Möglichkeit haben, nur nach "Karl" oder "Otto" zu suchen...???


Ergänzend zu allem was die anderen hier gesagt haben:
Mach dich vertraut mit der SQL-Sprache (respektive dem Dialekt, welche deine Datenbank benutzt).
Daran wirst du definitiv nicht vorbei kommen!
In deinem konkreten Fall (Suchen nach "Karl", "Otto" oder "Gedächtnisturnier") ist als erster ( ! ) Ansatz der LIKE-Operator zu nennen (wie auch schon oben erwähnt).

Was dir auch klar sein sollte: Die besten Quellen online sind zu 99% in englischer Sprache. Du solltest also keine Angst davor haben, entsprechend auch in englisch zu recherchieren.


----------



## Yaslaw (11. Januar 2021)

Als erstes musst du die Tabellen erstellen und lernen sie zu verknüpfen. Stichworte INNER JOIN und LEFT JOIN.
Dann kannst du das mit dem LIKE versuchen.
REGEX wie weiter oben geschrieben wird brauchst du nicht.
Ich habe keine Buch- oder Tutorialempfehlung, da mein letztes Buch zu diesem Thema etwa 15 Jahre alt ist und ich keine mehr brauche.


----------



## Tuppie (11. Januar 2021)

Yaslaw hat gesagt.:


> Als erstes musst du die Tabellen erstellen und lernen sie zu verknüpfen. Stichworte INNER JOIN und LEFT JOIN.
> Dann kannst du das mit dem LIKE versuchen.
> REGEX wie weiter oben geschrieben wird brauchst du nicht.
> Ich habe keine Buch- oder Tutorialempfehlung, da mein letztes Buch zu diesem Thema etwa 15 Jahre alt ist und ich keine mehr brauche.


Okay, dann bin ich im Verständnis einen wichtigen Schritt weiter. Heißt: in einer Spalte darf nur ein Wort stehen?
Bei Namen ja relativ leicht, dann eben seperate Spalten für Vor- und Nachname, aber bei meinem Beispiel von weiter oben ("Karl Otto Gedächtnisturnier") bin ich dann gezwungen, den Namen in verschiedene Spalten (hier drei Spalten) zu teilen, richtig? Soweit so okay, wenn man dann trotzdem nach "Karl Otto Gedächtnisturnier" suchen kann und einen entsprechenden Treffer bekommt. Klappt das dennoch?
Wäre zu blöd, wenn man einem Nutzer sagen müsste, dass er z.B. bitte nur nach "Karl" sucht.


----------



## Sprint (11. Januar 2021)

Tuppie hat gesagt.:


> An dieser Stelle: kennt Ihr hier einen guten Web- oder Buchtipp, man dem man sich diesbezüglich ordentlich einarbeiten kann?


Einen expliziten Tip habe ich nicht, aber die "für Dummies" Reihe ist für Einsteiger immer recht gut geeignet. Und wenn es wieder geht, würde ich mal in einen großen Buchladen gehen und mir verschiedene Bücher zu dem Thema anschauen. Oder du gehst den harten Weg und schickst die Bücher so lange hin und her, bis du eines gefunden hast, mit dem du gut zurecht kommst.


----------



## Yaslaw (11. Januar 2021)

Nein Tuppie. Du kannst den Namen auch in einem Feld lassen. Wie bereits mehrfach erwähnt ist LIKE die Lösung dazu.
Gehört zum Einmaleins von SQL. Findest du in jedem SQL-Buch ganz weit vorne.

Sorry, aber ich schreibe dir kein weiteres Buch oder Tutorial - da gibt es ganz viele. Und mit dem Begriff MySQL + LIKE findest du auch eim WWW ganz schnell Erklärungen.
Let Me Google That

Ansonsten noch ein Link zum Eintrag über LIKE im besten Nachschlagewerk für MySQL. 
MySQL :: MySQL 8.0 Reference Manual :: 12.8.1 String Comparison Functions and Operators


----------



## Tuppie (11. Januar 2021)

Okay, ganz lieben DANK für die vielen guten Anregungen und Hilfen. Ich lasse mir dass jetzt mal alles durch den Kopf gehen, überlege mir eine sinnvolle Struktur meiner (neuen) Datenbank und stelle die Euch dann mal vor, bevor ich zig Datensätze wieder umsonst anlege ;-)


----------



## Yaslaw (11. Januar 2021)

Gutes vorgehen. Wir werfen gerne nochmal ein Blick auf deine Umsetzung. Man kann am Anfang einer DB leider schon viel verbocken, was einem erst viel später auffällt und dann ist es meistens zu spät.


----------



## Tuppie (14. Januar 2021)

Eine prinzipielle Frage habe ich noch, bevor ich mich an die Denkarbeit mache ;-)
Wenn ich z.B. nach Teilnehmern abfrage, also wissen möchte, bei welchen Veranstaltungen Teilnehmer XY teilgenommen hat, dann möchte ich, dass die als Abfrageresultat ausgegeben Veranstaltungen direkt mit einer htm auf meiner Seite verlinkt sind, so dass man per Mausklick direkt auf die entsprechende Veranstaltungsseite geführt wird.
Geht so etwas? Müsste ich dann die Veranstaltungslinks in einer seperaten Tabelle anlegen?
Lieben Gruß


----------



## Yaslaw (14. Januar 2021)

Die Veranstalltungslinks kannst du bei der Veranstalltung speichern.


----------



## Tuppie (14. Januar 2021)

Yaslaw hat gesagt.:


> Die Veranstalltungslinks kannst du bei der Veranstalltung speichern.


Okay, dann kommen die Links in die veranstaltungstabelle... Danke!


----------



## Zvoni (15. Januar 2021)

Tuppie hat gesagt.:


> Okay, dann kommen die Links in die veranstaltungstabelle... Danke!


Bei solchen Sachen musst du dir eigentlich immer nur eine Frage stellen: ist es eine "1 zu 1"-Beziehung?
Falls Ja, kannst du es direkt in derselben Tabelle speichern.
Im konkreten Fall: Hast du jedesmal (also zu jeder Veranstaltung) immer auch nur einen Link?
Oder kann es sein, dass es mehrere Links gibt/geben wird (Bsp. 1 Link für Veranstaltungsort, 1 Link für Teilnehmer, 1 Link für Sponsoren etc.).

Solche Überlegungen gehören in den Bereich "Normalisierung"


----------



## Yaslaw (15. Januar 2021)

überleg dir einfach mal, wie eindeutig die Dinge sind.
Die Veranstalltung hat EINEN Link. Jeder Link gehärt genau zu EINER Veranstalltung.
Also kann an si in die gleiche Tabelle schreiben

Eine Veranstallung hat EINEN Veranstallter. Aber ein Veranstallter kann MEHRERE Veranstalltungen organisieren.
Also gehört der Veranstalter in eine Eigene Tabelle. In die Veranstalltungstabelle wird nur noch die ID des Veranstallters gespeichert.

Eine Veranstalltung hat MEHRERE Teilnehmer. Jeder Teilnehmer kann MEHRERE Veranstalltungen besuchen.
Da kommt das System wie weiter oben in diesem Thread erklärt. Eine Tabelle für die Teilnehmer und eine für die Zuordnung Teilnehmer <-> Veranstalltung.


----------



## Tuppie (17. Januar 2021)

Hallo,

ich habe mir nun für mein Projekt Folgendes überlegt. Zum eigentlichen Projekt, denn die "Sportveranstaltungen waren ein Beispiel: auf meiner Website liegen in Form von htm-Dateien Informationen zu Himalaya-Expeditionen. Nun möchte ich mittels einer Datenbank nach folgenden Kriterien suchen können: welche Exp. fanden in einem bestimmten Jahr statt? Welche Exp. wurden von Leiter XY als Leiter durchgeführt? Wer nahm an Exp. XY teil? Welche Exp. hatten z.B. den Mount Everest als Ziel?

Hier habe ich mir den Vorschlag von Yaslaw vom 10. Januar angeschaut und 5 Tabellen angelegt:
1.: Tabelle _expedition_ mit dem eindeutigen Namen und Link auf meiner Website. Die Einträge bekommen *eID* als Index
2.: Eine über *pID* sortierte Tabelle _personen_, jeder Name taucht hier 1x auf
3. in der Tabelle _teilnehmer_ weise ich den eID´s die entsprechenden pID´s zu
4. die Tabelle _leiter_ weise ich den *lID*´s die entsprechenden Exp. über eID zu
5. das entsprechenden Jahr in der Tabelle _jahr_ wird der Exp. über die jeweilige eID zugewiesen

Mir fällt gerade auf, dass die Tabelle expedition noch eine Spalte bekommen müsste, wo der Exp.leiter über die Angabe der lID klargemacht wird, oder wie löse ich die Sache am besten? Über die lID ist ja klar, welche Person das laut pID ist. Oder?

Gebt man bitte Euer Feedback, ob die Struktur so sinnvoll ist, das wäre mir sehr wichtig.
Dann kann ich die Tabellen mit Leben füllen, das wird dauern, und mich in der Zwischenzeit schlau machen, wie man die Daten dann abfragt.


----------



## Zvoni (18. Januar 2021)

Sieht gut aus.
Die Tabelle eID-Jahr halte ich für überflüssig. Die Jahresangabe kann man auch direkt in die Expeditions-Tabelle nehmen, da die Jahresangabe im Prinzip ein Integer ist (oder 4-stelliger Text). Du gewinnst also nichts im Sinne von "Reduzierung von Datenvolumen".

Und du hast die Jahresangabe eh schon im Text der Expedition.
Heisst: separate Spalte "Jahr", und die Jahresangabe im Text weglassen (kann man aber auch drin lassen)


----------



## Tuppie (18. Januar 2021)

Zvoni hat gesagt.:


> Sieht gut aus.
> Die Tabelle eID-Jahr halte ich für überflüssig. Die Jahresangabe kann man auch direkt in die Expeditions-Tabelle nehmen, da die Jahresangabe im Prinzip ein Integer ist (oder 4-stelliger Text). Du gewinnst also nichts im Sinne von "Reduzierung von Datenvolumen".
> 
> Und du hast die Jahresangabe eh schon im Text der Expedition.
> Heisst: separate Spalte "Jahr", und die Jahresangabe im Text weglassen (kann man aber auch drin lassen)


Danke Zvoni.

Ich dachte, die eID-Jahr-Tabelle wäre sinnvoll, da in einem Jahr verschiedene Exp. stattgefunden haben. Aber wahrscheinlich kann die wirklich raus.

Wie baue ich die Abfragemöglichkeit nach dem Exp.leiter am besten ein? Ein Teilnehmer einer jeden Exp. hatte die Leitung inne, es soll also auch eine Abfrage möglich sein, wie z.B. "Gib alle Exp. aus, bei denen XY Leiter war".


----------



## Zvoni (18. Januar 2021)

Aircode. Ausprobieren!

```
SELECT
expedition.Expedition,
expedition.Link
FROM
expedition, teilnehmer, leiter, person
WHERE
teilnehmer.eID=expedition.eID AND
leiter.lID=teilnehmer.pID AND
person.pID=leiter.pID AND
person.Vorname='Charles' AND
person.Nachname='Bruce'
```

EDIT: Nach Überlegung kannst du auch ein Feld "LID" direkt in Expedition einfügen (welches einen gültigen Eintrag auf die Person-Tabelle hat, welcher wiederum auch in der Teilnehmer-Tabelle vorkommen muss), und dir die "Mix"-Tabelle sparen
Die Abfrage würde dann in etwa so aussehen (Aircode)

```
SELECT
expedition.Expedition,
expedition.Link
FROM
expedition, teilnehmer, person
WHERE
teilnehmer.eID=expedition.eID AND
expedition.lID=person.pID AND
person.pID=teilnehmer.pID AND
person.Vorname='Charles' AND
person.Nachname='Bruce'
```


----------



## Tuppie (18. Januar 2021)

Zvoni hat gesagt.:


> Aircode. Ausprobieren!
> 
> ```
> SELECT
> ...


Ich danke Dir Zvoni für Deine Meinung & Zeit, ich werde probieren...


----------



## Tuppie (24. Januar 2021)

Ich versuche gerade (vergeblich), eine Abfrage zu formulieren, bei der mir die Teilnehmer einer konkreten Expedition angezeigt werden. Meine Abfrage sieht so aus:

_SELECT
personen.Vorname, personen.Nachname
FROM
expedition, teilnehmer, personen
WHERE
teilnehmer.pID=expedition.eID AND
expedition.eID=3_

In der Teilnehmerliste sind ja die entsprechenden Personen-ID´s "pID" den zugehörigen Expeditions-ID´s "eID" zugeordnet. Hier bekomme ich aber alle Namen ausgegeben, die in der Personentabelle eingetragen sind.  Warum funktioniert die eingrenzende Zeile 

_AND
expedition.eID=3
_
nicht? Bzw. wo ist mein Denkfehler?
Freue mich auf Kommentare...


----------



## Sprint (24. Januar 2021)

Im WHERE Teil fehlt die Beziehung zur Personen Tabelle. Daher wird da nichts eingegrenzt und es werden alle Namen ausgegeben.


----------



## Zvoni (24. Januar 2021)

Du musst teilnehmer.eID=expedition.eID und Teilnehmer.pID=person.pID vergleichen


----------



## Tuppie (24. Januar 2021)

Zvoni hat gesagt.:


> Du musst teilnehmer.eID=expedition.eID und Teilnehmer.pID=person.pID vergleichen


Ich danke Dir für den Hinweis, das hat den gewünschten Erfolg gebracht!
Jetzt habe ich mal eine funktionierende Abfrage über mehrere Tabellen hinweg und hoffe, dass mir das hilft, den Syntax als SQL-Neuling besser zu durchschauen!


----------



## Tuppie (26. Januar 2021)

Zunächst danke für die zurückliegenden, guten Hinweise, die es mir ermöglichen, an meiner DB zu arbeiten. Nun stoße ich auf ein Problem und finde keine Erklärung: ich habe eine Abfrage geschrieben, mit der man sich die Expeditionen anzeigen lassen kann, die ein bestimmter Leiter (bei mir über die Tabelle "Leiter" und eine entsprechende Leiter-ID lID zugeordnet) abfragen kann:

SELECT
expedition.expeditionsname, expedition.eID
FROM
expedition, teilnehmer, personen, leiter
WHERE
leiter.lID=expedition.lID AND
teilnehmer.pID=personen.pID AND
leiter.lID=personen.pID AND
leiter.lID=6

Bei lID=6 zeigt sich das Problem: eine kleine Expedition, nur zwei Teilnehmer, als Abfrageresultat bekomme ich die korrekte Exp. ausgegeben, aber gleich 2x. *Warum? *
Die beiden Teilnehmer tauchen in der Personentabelle nicht doppelt auf und auch in der Leiter-Tabelle gibt es keinen Doppelteintrag. *Was übersehe ich?* Bei anderen Exp. wird korrekt jede Exp. nur 1x ausgegeben, z.B. wenn man auf lID=6 prüft: zwei Exp., aber eben jeder Eintrag nur 1x.
Anbei die DB "als zip", bitte die Dateiendung nur gegen sql tauschen, wer sich das näher anschauen möchte.
*Ich danke* sehr für Eure aufmerksamen Hinweise!!!


----------



## Zvoni (27. Januar 2021)

Wenn du eine "LID" in Expedition hast, brauchst du keine "Leiter"-Tabelle


```
SELECT
expedition.expeditionsname, expedition.eID
FROM
expedition, teilnehmer, personen
WHERE
personen.pID=expedition.lID AND
teilnehmer.eID=expedition.eID AND  //DAS HIER FEHLT!
teilnehmer.pID=personen.pID AND
expedition.lID=6
```

Was mir aufgefallen ist: Bei eID=7 fehlt der Leiter (lID=6) in der Teilnehmer-Tabelle.
Und die Tabelle "Jahr" brauchst du auch nicht, da das Jahr direkt in Expedition steht

EDIT: Eine Tabelle "Leiter" brauchst du nur, falls es zwei oder mehr Leiter (Aus dem Kreis der Teilnehmer) pro Expedition gibt. In dem Fall darf es kein "LID" in Expedition geben!


----------



## Tuppie (27. Januar 2021)

Zvoni hat gesagt.:


> Wenn du eine "LID" in Expedition hast, brauchst du keine "Leiter"-Tabelle
> 
> Was mir aufgefallen ist: Bei eID=7 fehlt der Leiter (lID=6) in der Teilnehmer-Tabelle.
> Und die Tabelle "Jahr" brauchst du auch nicht, da das Jahr direkt in Expedition steht
> ...


Grüß Dich Zvoni,
danke Dir sehr für Deine abermalige Unterstützung.

*Zum Verständnis:* warum keine Leiter-Tabelle? Jede Exp. hat einen Leiter. Diese Person ist mit einer pID in der Personentabelle und wird in der Teilnehmertabelle einer Exp. oder mehreren Exp. zugeordnet. Wenn ich in der expedition-Tabelle einen Leiter per lID ausweise, dann muss ich doch über eine weitere Zuordnung sagen, welche pID welchem Leiter entspricht oder? Wie soll ich das sonst regeln?

*Zur eID=7: *die Exp. besteht aus nur zwei Personen, sie sind mit pID=53 und pID=54 in der Personentabelle, beide sind entsprechend in der Teilnehmertabelle der Exp.ID 7 zugeordnet. Und pID=53 ist als Leiter der Exp. mit einer lID=6 versehen, die ja auch in der expedition-Tabelle entsprechend auftaucht.
Ich bin nach wie vor ratlos, wo der Fehler ist bzw. wie Dein Hinweis "_Bei eID=7 fehlt der Leiter (lID=6) in der Teilnehmer-Tabelle_" gemeint ist.

Die Jahr-Tabelle kann weg, das sehe ich ein. Habe ich nur als Altlast weitergeführt, sollte ich rausschmeißen...

_Update:_ Deine Abfrage bringt mit lID=6 tatsächlich keinen Treffer, bei lID=5 aber auch nicht... 
Wenn ich hingegen Deine zusätzliche Abfrage-Zeile weglasse, dann bekomme ich z.B. bei einer Abfrage nach lID=5 korrekte Ergebnisse. Ich bin ratlos!

_Update:_ bei Abfrage so wie von mir gedacht bekomme ich z.B. bei Abfrage nach lID=1 ein Ergebnis - korrekt! Bei Abfrage nach lID=2 bekomme ich zwar das richtige Ergebnis, diesen Datensatz aber gleich doppelt angezeigt. Dieses Problem taucht mehrfach auf, so eben auch bei lID=7 (zwei korrekte Werte doppelt ausgegeben macht vier Datensätze im Abfrageergebnis...


----------



## Tuppie (27. Januar 2021)

gelöscht


----------



## Zvoni (27. Januar 2021)

Aber personen.pID=53 ist ja nicht der Leiter für eID=7
In deiner ursprünglichen Abfrage im WHERE (gekürzt)
leiter.lID=expedition.lID AND
leiter.lID=personen.pID AND
leiter.lID=6
Du setzt Leiter.lID auf 6 und verberbst die "6" an personen.pID (also person mit pID=6 ist der Leiter und nicht pID=53


----------



## Zvoni (27. Januar 2021)

Tuppie hat gesagt.:


> *Zum Verständnis:* warum keine Leiter-Tabelle? Jede Exp. hat einen Leiter. Diese Person ist mit einer pID in der Personentabelle und wird in der Teilnehmertabelle einer Exp. oder mehreren Exp. zugeordnet. Wenn ich in der expedition-Tabelle einen Leiter per lID ausweise, dann muss ich doch über eine weitere Zuordnung sagen, welche pID welchem Leiter entspricht oder? Wie soll ich das sonst regeln?


Ich versuch es mal so rum: Vergiss mal alle anderen Tabellen ausser Expedition und Personen.
In Expedition hat du eine "LID" welche auf eine "pID" von Personen weist.
Zeige mir alle Expeditionen, bei welchen pID=6 der Leiter war
SELECT 
expedition.eID, expedition.expeditionsname 
FROM 
expedition, personen
WHERE 
personen.pID=6 AND 
personen.pID=expedition.LID

Das würde dir alle expeditionen anzeigen, bei welchen pID=6 der Leiter war
Da du jetzt aber auch noch Teilnehmer hast, musst du Teilnehmer.eID mit expedition.eID vergleichen (woher soll das System wissen, welche Teilnehmer bei welcher Expedition waren?)
Man kann sich jetzt streiten, ob der Leiter auch in der Teilnehmer-Tabelle sein muss (muss er nämlich nicht!)

pID - Name
6 - Zvoni
7 - Tuppi
8 - Yaslaw

LID in expedition hat die 6
Teilnehmer sind aber wie folgt
eID - pID
7 - 7
7 - 8


----------



## Tuppie (27. Januar 2021)

Ohweia, also: die pID=6 ist laut meiner Personenliste eine Person, die *nichts* mit der Expedition zu tun hat, die mir bei Deiner Abfrage

SELECT 
expedition.eID, expedition.expeditionsname 
FROM 
expedition, personen
WHERE 
personen.pID=6 AND 
personen.pID=expedition.LID

ausgeworfen wird, nämlich die eID 7. Nimm es mir nicht übel, aber das verstehe ich nicht!?

*Update:*
An sich dachte ich, dass folgende Abfrage bei Eingabe eines Leiter-Nachnamens zum Erfolg führt:

SELECT
expedition.expeditionsname, expedition.eID
FROM
expedition, teilnehmer, personen
WHERE
personen.Nachname='Aufschnaiter' AND
teilnehmer.eID=expedition.eID AND
teilnehmer.pID=personen.pID AND
leiter.nachname= personen.Nachname

Klappt aber nicht, auch hier ist mir nicht klar, wieso nicht!?


----------



## Sempervivum (27. Januar 2021)

Ich stimme Zvoni zu, auch meiner Meinung nach ist die Tabelle Leiter redundant, denn sie enthält Vorname und Nachname, ebenso wie die Tabelle Personen.

Mir scheint mit der vorhandenen Struktur machst Du es dir in #33 viel zu kompliziert. Für mich ergibt dies genau das richtige und nur das eine Resultat:

```
SELECT expedition.expeditionsname, expedition.eID FROM expedition, leiter
    WHERE leiter.lID=expedition.lID
        AND leiter.lID=6
```

Ebenso in #39, hier führt für mich dies zum Ziel:

```
SELECT
    expedition.expeditionsname, expedition.eID
FROM
    expedition,leiter
WHERE
    leiter.Nachname='Aufschnaiter' AND
    expedition.lID = leiter.lID
```

Und wenn man alle Teilnehmer dieser Expedition haben möchte:

```
SELECT
        expedition.expeditionsname, expedition.eID, personen.Vorname, personen.Nachname
 FROM
        expedition, leiter, teilnehmer, personen
 WHERE
        leiter.Nachname='Aufschnaiter' AND
        expedition.lID = leiter.lID AND
        personen.pID = teilnehmer.pID AND
        teilnehmer.eID = expedition.eID
```


----------



## Zvoni (28. Januar 2021)

Tuppie hat gesagt.:


> Ohweia, also: die pID=6 ist laut meiner Personenliste eine Person, die *nichts* mit der Expedition zu tun hat, die mir bei Deiner Abfrage
> 
> SELECT
> expedition.eID, expedition.expeditionsname
> ...


Ah, OK. Habs gerade gesehen. Du hast Recht. Habe mich geirrt.
Du hast in der "Leiter"-Tabelle (die überflüssig ist), ein Feld "pID", welches der eigentliche Zeiger auf die Personen-Tabelle ist. Habs durcheinander gebracht.
Sempervivum hat Recht, dass du Redundanz in der Leiter-Tabelle hast (welche anderst ist als in deiner ersten Struktur).

Deine ursprüngliche Frage würde meine Lösung so aussehen:

```
SELECT
expedition.expeditionsname, expedition.eID
FROM
expedition, teilnehmer, personen, leiter
WHERE
leiter.lID=expedition.lID AND
teilnehmer.eID=expedition.eID AND  //DAS HIER FEHLT!
teilnehmer.pID=personen.pID AND
leiter.pID=personen.pID AND
leiter.lID=6
```


----------



## Tuppie (28. Januar 2021)

Sempervivum hat gesagt.:


> Ich stimme Zvoni zu, auch meiner Meinung nach ist die Tabelle Leiter redundant, denn sie enthält Vorname und Nachname, ebenso wie die Tabelle Personen.
> 
> Mir scheint mit der vorhandenen Struktur machst Du es dir in #33 viel zu kompliziert. Für mich ergibt dies genau das richtige und nur das eine Resultat:
> 
> ...


*DANKE Sempervivum* für die genial einfache Lösung, auf die ich nicht gekommen wäre, weil ich viel zu kompliziert gedacht habe und nicht weiter kam...
Die Namensangaben in der Leitertabelle sind für mich nur eine Gedächtnisstütze, damit ich nicht den Überblick verliere ;-)
Grundsätzlich ist die Tabelle leiter nicht redundant (für mich), da ich keine andere Lösung sehe, Leiter abzufragen. In der Personentabelle ist ja diesbezüglich keine Info vermerkt!?
Oder ich füge in der Tabelle expedition eine Spalte "Leiter" statt lID ein und trage hier die Namen gleich ein. Würde aber zwei Spalten für Nach- und Vorname bedeuten.
Die Teilnehmerabfrage hatte ich mir auch schon so zurecht gebastelt, aber bei der Leiterabfrage hackelte es...


----------



## Tuppie (28. Januar 2021)

Zvoni hat gesagt.:


> Ah, OK. Habs gerade gesehen. Du hast Recht. Habe mich geirrt.
> Du hast in der "Leiter"-Tabelle (die überflüssig ist), ein Feld "pID", welches der eigentliche Zeiger auf die Personen-Tabelle ist. Habs durcheinander gebracht.
> Sempervivum hat Recht, dass du Redundanz in der Leiter-Tabelle hast (welche anderst ist als in deiner ersten Struktur).
> 
> ...


*DANKE Zvoni *für Deinen abermaligen Rat!
Wie ich Sempervivum schon geschrieben hatte: die Tabelle leiter ist nur deshalb _nicht_ redundant für mich, weil ich keine andere Lösung sehe, einer Person aus der Tabelle personen diese Zusatzinformation aufzudrücken. Zwei zusätzliche Spalten "Vorname Leiter" und "Nachname Leiter" in der Tabelle expedition ist auch nicht besser, oder?


----------



## Sempervivum (28. Januar 2021)

> Grundsätzlich ist die Tabelle leiter nicht redundant (für mich), da ich keine andere Lösung sehe, Leiter abzufragen. In der Personentabelle ist ja diesbezüglich keine Info vermerkt!?


Das kann ich nicht nachvollziehen. In der Tabelle expedition hast Du doch die Leiter-ID und die kann problemlos auch auf eine Person in der Personentabelle verweisen. Dann hast Du auch Zugriff auf Vor- und Nachname ohne sie redundant in expedition zu führen. Der Leiter ist ja auch eine Person bzw. Teilnehmer an der Expedition. 


> In der Personentabelle ist ja diesbezüglich keine Info vermerkt!?


Ich dachte kurzzeitig daran, in der Personentabelle eine Kennung anzubringen, die angibt, ob es sich um einen Leiter handelt, aber das würde nicht passen, weil die selbe Person ja bei einer Exp. der Leiter sein kann, bei einer anderen aber nur Teilnehmer.


----------



## Tuppie (28. Januar 2021)

Sempervivum hat gesagt.:


> Das kann ich nicht nachvollziehen. In der Tabelle expedition hast Du doch die Leiter-ID und die kann problemlos auch auf eine Person in der Personentabelle verweisen. Dann hast Du auch Zugriff auf Vor- und Nachname ohne sie redundant in expedition zu führen. Der Leiter ist ja auch eine Person bzw. Teilnehmer an der Expedition.


Heißt, dass ich in der Personentabelle eine Spalte lID anlege und entsprechend fülle? Bei den meisten Personen bleibt das Feld dann frei, aber ist ja egal, oder?


Sempervivum hat gesagt.:


> Ich dachte kurzzeitig daran, in der Personentabelle eine Kennung anzubringen, die angibt, ob es sich um einen Leiter handelt, aber das würde nicht passen, weil die selbe Person ja bei einer Exp. der Leiter sein kann, bei einer anderen aber nur Teilnehmer.


Richtig! ;-)


----------



## Sempervivum (28. Januar 2021)

> Heißt, dass ich in der Personentabelle eine Spalte lID anlege und entsprechend fülle?


Auch hier kann ich dir nicht folgen. Wozu soll diese dienen, wenn es keine Tabelle leiter mehr gibt?
Beschreibe doch mal verbal eine Abfrage wo Du meinst, dass es nicht ohne die Leitertabelle geht.
Wenn Du eine Expedition hast, kannst Du über die Leiter-ID auf die Personentabelle zugreifen und Name und Vorname des Leiters lesen.
Und wenn Du Name und Vorname einer Person hast, kannst Du heraus finden, bei welchen Exp. sie Leiter war.


----------



## Tuppie (28. Januar 2021)

Sempervivum hat gesagt.:


> Auch hier kann ich dir nicht folgen. Wozu soll diese dienen, wenn es keine Tabelle leiter mehr gibt?
> Beschreibe doch mal verbal eine Abfrage wo Du meinst, dass es nicht ohne die Leitertabelle geht.
> Wenn Du eine Expedition hast, kannst Du über die Leiter-ID auf die Personentabelle zugreifen und Name und Vorname des Leiters lesen.
> Und wenn Du Name und Vorname einer Person hast, kannst Du heraus finden, bei welchen Exp. sie Leiter war.


Entschuldige meine Nachfrage: heißt, dass ich letztlich die Spalte lID z.B. in "Leiter" (muss nicht) umbenenne und dort die *pID* der Perosn eintrage, die eben bei dieser Exp. Leiter war. Korrekt?
Den Namen kann man sich dann ja in der Tat auswerfen lassen. 
Ich "fürchte", dass das klappt und ich mich fragen muss, warum ich so kompliziert gedacht habe...!?


----------



## Sempervivum (28. Januar 2021)

> heißt, dass ich letztlich die Spalte lID z.B. in "Leiter" (muss nicht) umbenenne und dort die *pID* der Perosn eintrage, die eben bei dieser Exp. Leiter war. Korrekt?


Ja, genau so stelle ich mir das vor und ich bin ziemlich sicher, dass man dann an alle Informationen heran kommt.


----------



## Tuppie (28. Januar 2021)

Sempervivum hat gesagt.:


> Ja, genau so stelle ich mir das vor und ich bin ziemlich sicher, dass man dann an alle Informationen heran kommt.


Ich sage abermals und sehr gerne *DANKE* für die abermalige Stellungnahme und Hilfe!
Ich probiere das morgen aus und stelle die DB mit einigen Abfragen mal auf die Probe.


----------



## Zvoni (29. Januar 2021)

Vielleicht zum besseren Verständnis, wie du dir die "Leiter"-Tabelle sparen kannst:
Du hast in Expedition ein Feld "pID" (anstatt "LID"), und dieses "pID" verweist DIREKT auf die "pID" in Personen, welche der Leiter ist.
Heisst aber auch: Jede Expedition kann auch nur einen Leiter haben (und nicht zwei oder mehr)

```
SELECT
expedition.expeditionsname, expedition.eID, personen.vorname, personen.nachname
FROM
expedition, teilnehmer, personen
WHERE
personen.pID=expedition.pID AND
teilnehmer.eID=expedition.eID AND
teilnehmer.pID=personen.pID AND
personen.pID=53
```

EDIT: Expedition.pID muss natürlich 53 sein (du hattest vorher LID=6 hier stehen)


----------



## Tuppie (29. Januar 2021)

Zvoni hat gesagt.:


> Vielleicht zum besseren Verständnis, wie du dir die "Leiter"-Tabelle sparen kannst:
> Du hast in Expedition ein Feld "pID" (anstatt "LID"), und dieses "pID" verweist DIREKT auf die "pID" in Personen, welche der Leiter ist.
> Heisst aber auch: Jede Expedition kann auch nur einen Leiter haben (und nicht zwei oder mehr)
> 
> ...


Danke Zvoni, genau. Irgendwie hatte ich diese einfachere und logische Lösung nicht auf dem Schirm. Zwei Leiter sind ab und an vorhanden, üblicherweise gibt es aber einen Namen, der da Vorrang hat. Mit den wenigen Ausnahmen muss ich mich dann arrangieren, wenn man dafür eine übersichtlichere Struktur haben kann.


----------



## Zvoni (29. Januar 2021)

Gibt es auch eine einfache Lösung dafür:
nennt sich m:n Beziehung 

kann ich dir am Montag helfen


----------



## Tuppie (29. Januar 2021)

Zvoni hat gesagt.:


> Gibt es auch eine einfache Lösung dafür:
> nennt sich m:n Beziehung
> 
> kann ich dir am Montag helfen


LIEBEN DANK schon jetzt und zunächst ein angenehmes Wochenende ;-)


----------



## Zvoni (1. Februar 2021)

Guten Morgen.
Also, zum Szenario "Expedition kann mehr als einen Leiter haben" ist wie gesagt eine klassische "m:n"-Beziehung. Allein um jetzt bei dir dieses Szenario zu implementieren wüsste ich zwei Vorgehensweisen.

Beide Varianten haben gemeinsam, dass es in Tabelle "Expedition" KEIN Feld "LID" bzw. pID" gibt, welches direkt auf einen Personensatz zeigt!!!!!

Variante 1)
In Tabelle "Teilnehmer" fügst du eine zusätzliche Spalte ein (Bsp. "Leiter"). Für diese Spalte benutzt du einen INTEGER-Datentyp (SmallINT, TinyInt, was auch immer) mit DEFAULT=0.
Die "0" bezeichnet einen Teilnehmer als normalen Teilnehmer, alles grösser 0 ist ein Leiter.
Ob du jetzt pauschal sagst, Leiter=1 ist ein Leiter, oder ob du eine Leiter-Hierarchie haben willst, ist dir überlassen.
Bsp. Zvoni hat Leiter=0, Fritz Müller hat Leiter=1, Hans Wurst hat Leiter=2
würde hier bedeuten:
Zvoni ist normaler Teilenehmer
Fritz Müller ist ein Leiter
Hans Wurst ist der Hauptleiter (weil er den höchsten Wert hat)
Eine Abfrage wie "Zeige mir für Expedition eID=17 alle Teilnehmer an, Die Leiter sollen als erstes hierarchisch ausgewiesen werden" könnte so aussehen:

```
SELECT
personen.vorname, personen.nachname
FROM
expedition, personen, teilnehmer
WHERE
teilnehmer.eid=expedition.eid AND
personen.pid=teilnehmer.pid AND
expedition.eid=17

ORDER BY
teilnehmer.Leiter DESC,
personen.nachname,
personen.vorname
```
Eine Abfrage "Zeige mir die Leiter für Expedtion eID=17" könnte so aussehen (Die Abfrage ist diesselbe wie oben drüber zzgl. des zusätzlichen Filters.

```
SELECT
personen.vorname, personen.nachname
FROM
expedition, personen, teilnehmer
WHERE
teilnehmer.eid=expedition.eid AND
personen.pid=teilnehmer.pid AND
expedition.eid=17 AND
teilnehmer.leiter>0
```

Variante 2)
Hinweis: Diese Variante nenne ich nur der Vollständigkeit halber!
Eine Zusätzliche Tabelle "Leiter" (Da haben wir die Tabelle wieder) mit folgenden Feldern:
eID --> Zeiger auf die Expedition
pID --> Zeiger auf die Person, welche Leiter ist
In dieser Variante brauchst du in Tabelle "Teilnehmer" KEINE zusätzliche Spalte (wie oben)
In dieser Konfiguration hast du aber wieder das Thema: Steht hier eine pID drin, ist es "ein" Leiter --> Keine Hierarchie! Willst du in dieser Variante eine Hierarchie haben, brauchst du auch hier eine zusätzliche Spalte "Hauptleiter" (oder ähnlich). Wieder mit Datentyp INTEGER.
Ob du hier die "0" als Hauptleiter machst, und alle mit einer "1" Nebenleiter sind, ist dir überlassen.
Die Abfragen sind aber um einiges komplizierter (Hier würde es dann losgehen mit UNION SELECT usw.)
Ich empfehle in deinem Fall eh Variante 1, weil man sich eine Tabelle sparen kann.
Desweiteren kannst du in die Situation kommen, dass z.B. Fritz Müller in Expedition 5 ein normaler Teilnehmer war, in Expedition 8 ist er ein Leiter, in Expedition 17 ist er Hauptleiter.
Ist mit Variante 1 deutlich einfacher zu handhaben.


----------



## Tuppie (1. Februar 2021)

Zvoni hat gesagt.:


> Guten Morgen.
> Also, zum Szenario "Expedition kann mehr als einen Leiter haben" ist wie gesagt eine klassische "m:n"-Beziehung. Allein um jetzt bei dir dieses Szenario zu implementieren wüsste ich zwei Vorgehensweisen.
> 
> Beide Varianten haben gemeinsam, dass es in Tabelle "Expedition" KEIN Feld "LID" bzw. pID" gibt, welches direkt auf einen Personensatz zeigt!!!!!
> ...


Lieber zvoni,
ganz  ganz herzlichen Dank, dass Du Dich tatsächlich dieser sehr speziellen Frage nochmals angenommen hast. Die Idee ist super und einfach umzusetzen, da ich derzeit erst knapp 30 Exp. in der DB habe. Zuerst wollte ich sehen, dass der Aufbau passt. So kann ich tatsächlich der Tatsache gerecht werden , dass es ab und an mehrere Leiter gibt, zumeist als "Hauptleiter" und "stellvertretender Leiter" angegeben. Probiere ich direkt mal an einer Stichprobe aus und berichte Dir morgen...
DANKE!


----------



## Tuppie (1. Februar 2021)

Zvoni hat gesagt.:


> Desweiteren kannst du in die Situation kommen, dass z.B. Fritz Müller in Expedition 5 ein normaler Teilnehmer war, in Expedition 8 ist er ein Leiter, in Expedition 17 ist er Hauptleiter.
> Ist mit Variante 1 deutlich einfacher zu handhaben.


Dieser Fall kommt übrigens recht häufig vor: ein Alpinist ist ja nie ausschließlich als Teilnehmer oder nur als Leiter unterwegs gewesen!


----------



## Zvoni (2. Februar 2021)

Ich habe die Tests mit eID=17 gemacht (4 Teilnehmer)
Geh mal auf Teilnehmer und filter nach eID=17, füge die Spalte hinzu, setz bei zweien die 0, bei den anderen eine 1 und eine 2.


----------



## Tuppie (2. Februar 2021)

Zvoni hat gesagt.:


> Ich habe die Tests mit eID=17 gemacht (4 Teilnehmer)
> Geh mal auf Teilnehmer und filter nach eID=17, füge die Spalte hinzu, setz bei zweien die 0, bei den anderen eine 1 und eine 2.


Ist schon sehr, sehr schön, wenn etwas klappt!!!
Ich DANKE Dir sehr für Deine Hilfe, bis ich mich revanchieren kann wird es noch 1001 Abfrage dauern ;-)

Eine Frage habe ich dennoch: in manchen Spalten kann ich Inhalte schnell und komfortabel gleich in der Tabelle ändern, z.B. bei Vertipsern. Bei anderen Spalten klappt das nicht, so dass man deutlich mühsamer mit UPDATE arbeiten muss. Wieso das?


----------



## Zvoni (3. Februar 2021)

Welche Spalten wären das? Beispiel?


----------



## Tuppie (3. Februar 2021)

Zvoni hat gesagt.:


> Welche Spalten wären das? Beispiel?


In der Tabelle expedition kann ich z.B. problemlos Werte ändern, egal ob Zahlwerte oder Text (z.B. den Link). In der Tabelle teilnehmer könnte ich keine Werte in der Tabelle selbst ändern, sondern müsste das per UPDATE machen, was natürlich länger dauert.


----------



## Zvoni (4. Februar 2021)

Welche Spalten in Teilnehmer? eID und pID, oder die Spalte "Leiter"?
bei eID und pID kann es sein, weil du Foreign Key constraints vielleicht drauf hast


----------



## Tuppie (4. Februar 2021)

Zvoni hat gesagt.:


> Welche Spalten in Teilnehmer? eID und pID, oder die Spalte "Leiter"?
> bei eID und pID kann es sein, weil du Foreign Key constraints vielleicht drauf hast


In der Tabelle teilnehmer kann ich weder bei eID noch bei pID Änderungen in der Tabelle selber vornehmen. Bei Einrichtung der Tabelle haben ich keine speziellen Optionen gewählt. Mit "Foreign Key constraints" kann ich nichts anfangen - sorry.


----------



## Zvoni (5. Februar 2021)

Klingt nach constraints.
Was benutzt du, wenn du direkt auf MySQL arbeitest? MySQL Workbench?
Schau mal in der Tabellen-Definition nach, ob bei eID und pID so etwas wie "Foreign Key" steht.
In Workbench sieht man das am einfachsten, wenn du ein Create Table-Statement erzeugst und es dir in einem Text-Editor anschaust.

Oder häng mal einen Screenshot hier rein von der Tabellen-Definition


----------



## Tuppie (5. Februar 2021)

Zvoni hat gesagt.:


> Klingt nach constraints.
> Was benutzt du, wenn du direkt auf MySQL arbeitest? MySQL Workbench?
> Schau mal in der Tabellen-Definition nach, ob bei eID und pID so etwas wie "Foreign Key" steht.
> In Workbench sieht man das am einfachsten, wenn du ein Create Table-Statement erzeugst und es dir in einem Text-Editor anschaust.
> ...


Ich arbeite mit phpMyAdmin. In den entsprechenden Spalten ist - für mich - nichts Verdächtiges zu sehen. In allen anderen Optionen (nicht mehr im Screenshot) ist gar nichts eingetragen.


----------



## Zvoni (6. Februar 2021)

Hmmm, seltsam.....
hab keine weitere Idee was das sein könnte


----------



## Sempervivum (6. Februar 2021)

Fehlen da die Buttons für "Bearbeiten" "Kopieren" "Löschen"? Bei mir ist es so, dass ich die Einträge in phpmyadmin nur ändern kann, wenn es eine unique-Spalte gibt.
	

		
			
		

		
	



	

		
			
		

		
	
 gibt.


----------



## Tuppie (7. Februar 2021)

Sempervivum hat gesagt.:


> Fehlen da die Buttons für "Bearbeiten" "Kopieren" "Löschen"? Bei mir ist es so, dass ich die Einträge in phpmyadmin nur ändern kann, wenn es eine unique-Spalte gibt.
> 
> 
> 
> ...


Sorry der späten Antwort!
Ja richtig, die Möglichkeiten für "Bearbeiten" "Kopieren" "Löschen" fehlen in den entsprechenden Tabellen.


----------



## Sempervivum (7. Februar 2021)

Dann brauchst Du eigentlich nur eine Spalte "unique" zu machen aber das wird bei der Tabelle teilnehmer nicht möglich sein, weil es keine Spalte gibt, wo jede ID nur einmal vorkommt. Bleibt nur die Möglichkeit, zusätzlich eine unique ID hinzu zu fügen.


----------



## Tuppie (8. Februar 2021)

Sempervivum hat gesagt.:


> Dann brauchst Du eigentlich nur eine Spalte "unique" zu machen aber das wird bei der Tabelle teilnehmer nicht möglich sein, weil es keine Spalte gibt, wo jede ID nur einmal vorkommt. Bleibt nur die Möglichkeit, zusätzlich eine unique ID hinzu zu fügen.


Verstehe, danke für den Hinweis. Ich kann so damit leben, an den meisten Stellen kann ich ja bequem & schnellkorrigieren sofern nötig.


----------



## Sempervivum (8. Februar 2021)

Eine ultimative Lösung wäre, für die Pflege der Datenbank Formulare einzurichten, aber vermutlich bist Du als Webmaster der einzige, der sie pflegt und kannst damit leben, die IDs manuell einzutragen.


----------



## Zvoni (8. Februar 2021)

Sempervivum hat gesagt.:


> Dann brauchst Du eigentlich nur eine Spalte "unique" zu machen aber das wird bei der Tabelle teilnehmer nicht möglich sein, weil es keine Spalte gibt, wo jede ID nur einmal vorkommt. Bleibt nur die Möglichkeit, zusätzlich eine unique ID hinzu zu fügen.


Nicht ganz.
Man kann auch beide Spalten eID und pID gemeinsam als UNIQUE deklarieren (kombinierter Primary Key), welches sogar logisch ist:
Die Kombination aus Expedition und Teilnehmer kann ja tatsächlich nur einmal vorkommen.
Nur eID oder nur pID als UNIQUE geht nämlich nicht (wie schon geschrieben!).

Die "Krücken"-Lösung ist eine zusätzliche anonyme Spalte als Primärschlüssel zu deklarieren, was in meinen Augen Unsinn ist, weil (zumindest derzeit) die Tabelle Teilnehmer nicht als Master-Tabelle verwendet wird, welche unter Umständen auf eine Detail-Tabelle verzweigt (wie auch schon beschrieben)


----------



## Tuppie (11. Februar 2021)

So, jetzt habe ich die DB etwas nach Euren Anregungen entschlackt: keine Tabelle Jahr, keine Tabelle Leiter.
Stattdessen nach Zvonis Anregung eine Spalte Leiter in der Tabelle teilnehmer eingefügt und alle Teilnehmer, die bei einer Expedition die Leiterrolle inne haben, mit dem Wert 1 versehen.
Nun frage ich mich, wie ich mir für einen bestimmten Nachnamen alle Exp. ausgeben lassen kann, wo die Person mit entsprechendem Nachnamen Leiter war. Ich dachte, dass Folgendes zum Erfolg führt, tut es aber nicht:

SELECT
    expedition.expeditionsname, expedition.eID, expedition.Leiter
FROM
    expedition,personen,teilnehmer
WHERE
    personen.Nachname='Herrligkoffer' AND
    teilnehmer.pID=personen.pID AND
    teilnehmer.Leiter=1

Diese konkrete Abfrage müsste nun zwei Treffer ausgeben, passiert aber nicht, ich bekomme deutlich mehr Ergebnisse. Dabei dachte ich, ich hätte eindeutig eingegrenzt!?
Was stimmt hier nicht oder fehlt gar noch?


----------



## Sempervivum (11. Februar 2021)

Wenn ich das richtig sehe, fehlt da noch die Verknüpfung zur Expedition:

```
SELECT
    expedition.expeditionsname, expedition.eID
FROM
    expedition,personen,teilnehmer
WHERE
    personen.Nachname='Herrligkoffer' AND
    teilnehmer.pID=personen.pID AND
    teilnehmer.eID=expedition.eID AND -- dies fehlte
    teilnehmer.Leiter=1
```
Und wenn Du in der Tabelle expedition eine Spalte leiter hast, fährst Du zweigleisig: Wenn ich Zvonis Ansatz richtig verstehe ist diese Spalte überflüssig.

BTW: Super Hinweis von Zvoni, dass man auch zwei Spalten als unique definieren kann, funktioniert einwandfrei und hat einen doppelten Eintrag in meiner Tabelle teilnehmer aufgedeckt.


----------



## Zvoni (12. Februar 2021)

Sempervivum hat gesagt.:


> Wenn ich das richtig sehe, fehlt da noch die Verknüpfung zur Expedition:
> 
> ```
> SELECT
> ...


Korrekt. Spalte "Leiter" in expedition ist überflüssig.

Als generellen Tip an Tuppie:
Immer wenn du eine Abfrage über mehrere Tabellen generieren willst, kannst du wie folgt vorgehen:
Leeres Blatt Papier im Querformat vor dich legen
Was will ich? --> Expeditionsname --> Also ist Tabelle expedition die am weitesten links (hinschreiben)
Welche Kriterien habe ich? --> Die Teilnehmer ---> Tabelle Teilnehmer rechts von expedition
Was ist mein Filter für die Teilnehmer? --> Ein Personen-Name --> Tabelle personen rechts von Teilnehmer

So kannst du sehen, welche Verknüpfungen du benötigst:
expedition zu Teilnehmer
Teilnehmer zu person

Ein "WHERE Tabelle1.EinFeld=Tabelle2.EinFeld" ist eine Verknüpfung
Ein "WHERE Tabelle1.EinFeld=EinWert" Ist ein Filter


----------



## Tuppie (12. Februar 2021)

Zvoni hat gesagt.:


> Korrekt. Spalte "Leiter" in expedition ist überflüssig.
> 
> Als generellen Tip an Tuppie:
> Immer wenn du eine Abfrage über mehrere Tabellen generieren willst, kannst du wie folgt vorgehen:
> ...


Ein dickes *DANKE an zvoni und sempervivum* für die Lösung des Problems und den guten Allgemeinhinweis von zvoni - das werde ich probieren!
Die Spalte Leiter in der Tabelle expeditionen ist tatsächlich hinfällig, ich hatte sie noch belassen, bis die Leiterabfrage klappt. Klappt ja nun! ;-) 

Achja, das UNIQUE-setzen von eID und pID in teilnehmer hat geklappt, der Doppeleintrag ist beseitigt.
Hierzu: gibt es einen Befehl, der bei derartigen Mehrfacheinträgen alle Dubletten _bis auf einen Eintrag_ (der soll ja vorhanden bleiben) rausschmeißt?


----------



## Zvoni (12. Februar 2021)

Sowas brauchst du nur, wenn die Spalte( n) nicht UNIQUE sind.
Ich glaube mich daran zu erinnern, dass hier um DB-Forum es schon den ein oder anderen Lösungsansatz gab. Musst mal forschen.


----------



## Tuppie (12. Februar 2021)

Zvoni hat gesagt.:


> Sowas brauchst du nur, wenn die Spalte nicht UNIQUE sind.
> Ich glaube mich daran zu erinnern, dass hier um DB-Forum es schon den ein oder anderen Lösungsansatz gab. Musst mal forschen.


Brauchst nicht forschen, danke, dann habe ich mit der UNIQUE-Option ja alles in die richtigen Wege geleitet.


----------



## Tuppie (22. März 2021)

Dank Eurer Hilfe gedeiht meine DB mehr und mehr.
Nun habe ich erstmals wieder ein Problem, wo ich nicht weiß, wie ich verfahren soll: ich habe in meiner Personenliste erstmalig zwei Personen mit identischem Vor- und Nachnamen, die aber nachweislich verschiedene Personen darstellen. Hat jemand eine Idee, wie man das unterscheidet?
Wenn ich jetzt eine Abfrage stelle "gib mir alle Expeditionen aus, an denen xy teilgenommen hat", dann gibt es momentan wegen dieser Dopplung natürlich falsche Ergebnisse.


----------



## Zvoni (22. März 2021)

In einer reinen Anzeige, in welcher man nur über den Namen filtert?
Wüsste ich auch nicht.
zweimal Fritz Müller bleibt zweimal Fritz Müller (auch wenn es unterschiedliche Personen sind),
es sei denn du hast weitere Unterscheidungsmerkmale (Bsp. zweiter Vorname, Geburtstag oder Alter, aber auch das ist nicht wasserdicht).


----------



## Tuppie (22. März 2021)

Zvoni hat gesagt.:


> In einer reinen Anzeige, in welcher man nur über den Namen filtert?
> Wüsste ich auch nicht.
> zweimal Fritz Müller bleibt zweimal Fritz Müller (auch wenn es unterschiedliche Personen sind),
> es sei denn du hast weitere Unterscheidungsmerkmale (Bsp. zweiter Vorname, Geburtstag oder Alter, aber auch das ist nicht wasserdicht).


Ja richtig.
Dachte mir schon, dass es da keinen "Kniff" gibt, um das Problem(chen) zu lösen. Dann werde ich in den Expeditionseiten, also in die entsprechenden htm-Seiten, Hinweise geben, damit es keine Verwechslungen gibt. Derlei sollte die große Ausnahme bleiben...


----------



## Zvoni (22. März 2021)

Das einzige, was mir eingefallen ist, wäre vielleicht eine ROW-NUMBER in Klammern mit auszugeben (PARTITION BY pID)
So in der Art: 
"Fritz Müller (1)"
"Fritz Müller (2)"
um anzuzeigen, dass es nicht dieselbe Person ist.
Müsste ich aber rumprobieren


----------



## Tuppie (22. März 2021)

So etwas Ähnliches habe ich schon einmal gesehen, weiß aber nicht, wie es "technisch" umgesetzt ist. Bei einer Personenabfrage soll ja schließlich nur der Name angezeigt werden und nicht (1) ect. Ich habe keine Ahnung, wie das geht...
Ich bin natürlich für jeden Tipp sehr dankbar!


----------

