MySql - Frage zu n:m Beziehung

CPoly

Mitglied Weizenbier
Hi,

Angenommen ich habe folgende drei Tabellen, mit welchen ich jeder Person beliebige Eigenschaften zuordnen kann:
-personen,
-eigenschaften,
-zuordnung

Jetzt möchte ich alle Personen, die die Eigenschaften 1,2 und 3 haben. Meine Abfrage sieht im Moment folgendermaßen aus.

SQL:
SELECT personen_id FROM zuordnung
WHERE eigenschaften_id IN (1,2,3)
GROUP BY personen_id
HAVING COUNT(*)=3

Das kann aber doch nicht die Lösung sein. Oder geht man bei einer so normalisierten Struktur wirklich so vor? Ich störe mich besonders an der letzte Zeile.
Also wie muss die Abfrage "richtig" aussehen?
 
Hallo,

bei der Abfrage rufst du alle Personen ab, die eine der 3 Eigenschaften haben -> "WHERE eigenschaften_id IN (1,2,3)"
Nur wenn alle 3 Eigenschaften vorhanden sind -> "HAVING COUNT(*)=3", wird die personen_id ausgegeben. Die personen_id wird nur einmal ausgegeben, obwohl diese 3x vorhanden ist -> "GROUP BY personen_id".
Das mal kleine Erklärung zu der Abfrage.

Mir fällt jetz auch nicht ein, wie man das anders machen könnte / warum man das nicht so machen sollte. Also ich denke, dass deine Lösung richtig ist.

Gruß
BK
 
Danke erstmal für die Antwort.

bei der Abfrage rufst du alle Personen ab, die eine der 3 Eigenschaften haben -> "WHERE eigenschaften_id IN (1,2,3)"
Nur wenn alle 3 Eigenschaften vorhanden sind -> "HAVING COUNT(*)=3", wird die personen_id ausgegeben. Die personen_id wird nur einmal ausgegeben, obwohl diese 3x vorhanden ist -> "GROUP BY personen_id".

Denke für die Erklärung, genau so war es ja von mir beabsichtigt ;)

Mir fällt jetz auch nicht ein, wie man das anders machen könnte / warum man das nicht so machen sollte. Also ich denke, dass deine Lösung richtig ist.

Ich dachte nur, dass sowas bei normalisierten Tabellen doch ständig vorkommt und es da vielleicht irgendwas gibt, wovon ich noch nichts weiß ;). Und "liefert das richtige Ergebnis" ist nicht das gleiche wie "richtig".
Ohne Normalisierung würde es ja ganz einfach funktionieren:
SQL:
SELECT id FROM personen WHERE eigenschaft_a=1 AND eigenschaft_b=2 AND eigenschaft_c=3;

Aber da will ich natülich nicht hin, zumal es keine Beschränkung gibt, wie viele Eigenschaften eine Person haben kann und nach welchen ich Suche.

Grüße
 
Wenn du sicher sein willst, dass jede Eigenschaft dabei nur einmal pro Benutzer vorkommt und es genau diese Eigenschaften sind, kannst du auch so etwas machen
SQL:
SELECT personen_id
FROM zuordnung
GROUP BY personen_id
HAVING GROUP_CONCAT(eigenschaften_id ORDER BY eigenschaften_id SEPARATOR ",") = "1,2,3"
 
Zuletzt bearbeitet von einem Moderator:
Danke nochmal für die Antworten.

Wenn du sicher sein willst, dass jede Eigenschaft dabei nur einmal pro Benutzer vorkommt

Die beiden Spalten in der Tabelle "zuordnung" haben einen UNIQUE-Index.

Ich weiß nicht, ob die Konkatenation über mehrere hunderttausend Spalten so performant ist. Und es müssen nicht genau die drei sein, sondern die drei sollen bei der Person vorkommen, unabhängig davon, ob die Person noch weitere Eigenschaften hat.
Meine Eingangs vorgestellte Abfrage liefert genau das, was ich will, nur wollte ich sicher gehen, dass es auch auch der beste Weg ist.

Grüße.
 
Zurück