Es kommt oft vor, dass wir nicht normalisierte Tabellen in MySQL mit Feldern, die Kommagetrennte Werte enthalten, ähnlich wie per JOIN abfragen möchten. Das ist leider ohne weiteres nicht möglich, da aufgrund der 1-ten Normalisierung jeder Wert in einer eigenen Zeile geschrieben werden soll, damit der JOIN funktionieren kann. Stellen Sie sich vor Sie haben eine alte und große Tabelle, die Felder in folgender Form enthält:
Spaltenname: SelectedIDs
Werte: 1,5,23,333,2315
Das erste, was man machen würde um die Werte abzufragen, wäre eine Abfrage mit WHERE … IN (wert1, wert4):
SELECT Name FROM Tabelle WHERE MeineID IN (SelectedIDs)
Das funktioniert leider nicht, da die Kommagetrennte Werte in dieser Form nicht an IN(…) übergeben werden können, im Gegensatz zu einem Array aus ein SELECT oder eine wirklich reingeschriebene Zeichenkette – 1,24,54 usw. Die PHP Funktion EXPLODE(TRENNZEICHEN, ZEICHENKETTE) generiert ein Array, der so ähnlich von MySQL generiert werden könnte, um an die WHERE … IN (AUS_EXPLODE_ARRAY) übergeben werden kann. MySQL unterstützt leider kein EXPLODE, reguläre Ausdrücke aber schon. Das wird nämlich unsere Programmierlösung für die Kommagetrennten Werte, die wir abfragen möchten.
Lösung
Es ist auch nicht immer möglich die Tabelle zu normalisieren, deswegen gibts es eine Erleichterung der Programmierung an der Stelle. Betrachten wir folgende zwei Tabellen:
Tabelle1
—————-
Name - Michael
MeineID – 2
Tabelle2
—————–
KlausurName – Englisch
SchulerIDs - 1,2,5,6
Wir haben hier den Michael, der die Klausur Englisch, zusammen mit vier anderen Schülern geschrieben hat. Wie bekommen wir ein JOIN auf die Zwei Tabellen? Folgende Abfrage kümmert sich mit einem regulären Ausdruck darum:
SELECT Name, MeineID, (SELECT KlausurName FROM Tabelle2 WHERE Tabelle1.MeineID REGEXP REPLACE(SchulerIDs, ‘,’, ‘|’)) as GeschriebeKlausur FROM Tabelle1
An der Stelle kommt der reguläre Ausdruck ins Spiel – WHERE MeinWert REGEXP (Wert1|Wert3|Wert4) gibt Wahr zurück, wenn einer der mit der Pipeline getrennten Werte mit MeinWert übereinstimmt. Mit der Funktion REPLACE wird die kommagetrennte Zeichenkette für den regulären Ausdruck aufbereitet – die Kommas werden durch ein Pipeline ersetzt. Das bedeutet, dass Ihre Werte beliebig getrennt werden können, Sie müssten einfach den zweiten Parameter der REPLACE Funktion berücksichtigen.
Somit macht MySQL einfach Spass!
use-media - Ihr professioneller Webdesigner
Wir sind Ihr kompetenter Partner im Bereich Programmierung und Webdesign. Als Full-Service Agentur betreuuen wir Ihr Unternehmen von der Gestaltung Ihres Internetauftritts bis zur Analyse der besten Mittel für Ihr Online Marketing.
Auch Kleinanforderungen werden schnell erledigt, auch im Ghostwriting - nehmen Sie Kontakt mit uns auf.

| Tags: 


Danke für die Hinweise. Damit das Ganze ggf. auch mit Strings und nicht nur mit uids funktioniert, muß Michele Marschings Abfrage noch ganz leicht erweitert werden:
SELECT Name, MeineID, (SELECT KlausurName FROM Tabelle2 WHERE Tabelle1.MeineID REGEXP CONCAT(’^(’, REPLACE(SchulerIDs, ‘,’, ‘$|^’), ‘)$’) as GeschriebeKlausur FROM Tabelle1
Hi Michele,
vielen Dank für deinen Beitrag. Wir hoffen das bringt viele Leute noch wieter!
Wie stellst du dir das mit dem HAVING am Ende, wo wir keine aggregate Funktion haben?
Viele Grüße
Nachtrag: Ein HAVING GeschriebeneKlausur am Ende der Abfrage hilft bei großen Zahlen auch ungemein
Grüße | Michele
Das ganze hat so bei mir leider nicht funktioniert, aber ich habe eine Lösung gefunden: Ich musste das REGEXP noch erweitern!
Auf das obige Beispiel bezogen funktioniert bei mir die Abfrage so:
SELECT Name, MeineID, (SELECT KlausurName FROM Tabelle2 WHERE Tabelle1.MeineID REGEXP CONCAT(‘^(‘, REPLACE(SchulerIDs, ‘,’, ‘|’), ‘)$’) as GeschriebeKlausur FROM Tabelle1
… damit wird sichergestellt, dass auch nur die IDs gefunden werden, die in dem Feld stehen… vor der Änderung findet er mit den IDs 1,2,5,6 auch die Schüler 10-19 (kommt eine 1 drin vor), die Schüler 20-29 (wegen der 2), die Schüler 31,32,35,36,41,42,45,46,50+ usw…
Mit der Änderung stellen wir sicher, dass der Ausdruck mit einer der Zahlen in den Klammern beginnt (^) und auch endet ($). Also finden wir nur noch exakte Treffer und das REGEXP funktioniert auch mit größeren Zahlen!
Grüße | Michele