ist wahrscheinlich ne Anfängerfrage, von daher – schon mal sorry ;-). Ich habe folgendes Problem:
Ich habe insgesamt 3 Tabellen, nämlich [betriebe], [kontakte] und [infomaterial]. Wenn wir mit den Betrieben Kontakt haben, vereinbaren wir oft, dass diese Infomaterial erhalten – dies können mehrere verschiedene Infomaterialien sein.
Der Mitarbeiter erfasst also unter [kontakte] durch Anklicken mehrerer Checkboxen das zu versendende Infomaterial. Dabei wird dem Feld [kontakte].[infomaterial] die jeweilige id des infomaterials hinzugefügt – und zwar mit Komma getrennt in ein Feld vom Typ „Tinytext“.
Dieses Feld hat also z. B. folgenden Inhalt: 4,3,15,7
Nun möchte ich bei einer Abfrage nach Eingabe der Betriebs-ID beim Feld [betriebe].[betriebs_id] alle Infomaterialien aufgelistet bekommen, die dieser Betrieb bekommt.
Problem: Ich habe keine Ahnung, wie ich den mehrfachen Inhalt des Feldes [kontakte].[infomaterial] als Kriterium heranziehen soll.
Wie man sieht, wird unter [kontakte] die betriebs_id aus [betriebe] als Fremdschlüssel gespeichert. Hier hätte ich also eine Verbindung und die brauche ich auch, da ich NUR aufgrund des Kriteriums [betriebs_id] diese Abfrage starten kann.
Aber wie bekomme ich es per SQL hin, dass ich aufgrund der Eingabe der betriebs_id eine Auflistung des Infomaterials (und zwar eine Zeile pro Infomaterial) mit den Daten [infomaterialname] und [infomaterialbeschreibung] erhalte?
Gäbe es da dieses „FIND IN“ oder „FIND IN SET“ oder so?
Als erstes solltest du dein Tabellendesign ändern: Alle IDs als String in einer Spalte zu speichern ist nämlich keine gute Grundlage (Siehe Normalform). Ich würde also vorschlagen, die kontakt-Tabelle erst einmal in eine Verbindungstabelle abzuändern (Die vorhandenen Einträge der Tabelle müssen natürlich wieder importiert werden):
Code:
CREATE TABLE kontakte (
betriebs_id int(10) unsigned NOT NULL,
infomaterial_id int(10) unsigned NOT NULL,
PRIMARY KEY (betriebs_id,infomaterial_id)
) ENGINE=MyISAM;
Damit lässt sich dann das gewünschte Ergebniss erzielen:
Code:
SELECT i.infomaterial_id
, i.infomaterialname
, i.infomaterialbeschreibung
FROM betriebe AS b
INNER
JOIN kontakte AS k
ON k.betriebs_id = b.betriebs_id
INNER
JOIN infomaterial AS i
ON i.infomaterial_id = k.infomaterial_id
WHERE b.betriebs_id = 123;
Das wäre natürlich eine Möglichkeit, damit hätte ich eine saubere Verbindung zwischen den Tabellen.
Das Problem ist halt, dass ich die Abfrage nicht "einmal und nie wieder" ausführen will, sondern das ist ein laufender Prozess. Wir haben in Zukunft immer wieder Kontakt mit Kunden, denen wir dann Infomaterialien zuordnen - die müssten ja dann alle einzeln gespeichert werden.
Ich müsste pro durchgeführten Kontakt mehrere Infomaterialien speichern können - und da ist mir bislang nur diese "Zahlenkolonne" im Feld "Infomaterial" eingefallen.
Ich hab mal als Screenshot die Oberfläche für die Kontakterfassung beigefügt, vielleicht kann man sich das dann besser vorstellen.
Ok, Ich glaub ich habs verstanden. Aber auch dann ist die Normalisierung der beste Weg. Glaub mir, die IDs als String in einer Spalte verursachen nur Probleme. Wenn nicht jetzt, dann sicher irgendwann in der Zukunft.
Also noch ein Versuch. :D In dieser Tabelle speicherst Du die Beziehung des Kontakts zum Infomaterial:
Code:
CREATE TABLE kontakte_zu_infomaterial (
kontakt_id int(10) unsigned NOT NULL,
infomaterial_id int(10) unsigned NOT NULL,
PRIMARY KEY (kontakt_id, infomaterial_id)
) ENGINE=MyISAM;
Für jede Infomaterial-ID wird also eine extra Reihe eingetragen:
PHP-Code:
$sql->query("INSERT INTO kontakte (kontakt_id, betriebs_id) VALUES (NULL, ". $betriebs_id .")");
Die erste Abfrage besteht ja wahrscheinlich schon. Ich zeig das ganze nur noch einmal um die Interaktion mit mysql_insert_id und der nachfolgenden Tabelle zu erklären.
Mit dieser Abfrage bekommt man dann das gewünschte Ergebniss:
Code:
SELECT i.infomaterial_id
, i.infomaterialname
, i.infomaterialbeschreibung
FROM betriebe AS b
INNER
JOIN kontakte AS k
ON k.betriebs_id = b.betriebs_id
INNER
JOIN kontakte_zu_infomaterial AS ki
ON ki.kontakt_id = k.kontakt_id
INNER
JOIN infomaterial AS i
ON i.infomaterial_id = k.infomaterial_id
WHERE b.betriebs_id = 123;
Ich muss jetzt versuchen, dass bei mir unterzubekommen. Ich brauch das für ne Seite, die mit TYPO3 erzeugt wurde und da konnte ich PHP bisher fast komplett umgehen :-) Bin nämlich blutiger PHP-Anfänger.