Join über mehrere Tabellen/Suche nach Zuordnungen
Marc D
- datenbank
0 Vinzenz Mai0 Ilja
Hallo,
ich habe ein kleines Problem mit einer Query, bei der ich Personen mit Eigenschaften suchen möchte. Das ganze läuft mit Postgres 8.3.
Meine Tabellen lauten:
People: id, name
Feature: id, name
Personfeatures: id, person_id, feature_id
Nun möchte ich Personen suchen, die zwei oder mehrere Eigenschaften haben.
Eine Anfrage in der Art:
SELECT p.id, p.name FROM people AS p INNER JOIN personfeatures AS pf ON pf.person_id = p.id WHERE pf.feature_id = 1 AND pf.feature_id = 2
liefert mir ja kein Ergebnis, da es keinen einzelnen Datensatz gibt, der beide ids gleichzeitig hat.
Mir sind nun zwei Lösungen eingefallen:
SELECT p.id, p.name FROM people AS p INNER JOIN personfeatures AS pf ON pf.person_id = p.id WHERE pf.feature_id = 1 OR pf.feature_id = 2 GROUP BY p.id HAVING count(p.id) = 2
oder
SELECT p.id, p.name FROM people AS p INNER JOIN personfeatures AS pf1 ON pf1.person_id = p.id INNER JOIN personfeatures AS pf2 ON pf2.person_id = p.id WHERE pf1.feature_id = 1 AND pf2.feature_id = 2
Gibt es noch eine elegantere Lösung? Wenn nein, welche meiner Lösungen wäre eurer Meinung nach zu bevorzugen.
Vielen Dank für die Hilfe
Marc
Hallo,
Meine Tabellen lauten:
People: id, name
Feature: id, name
Personfeatures: id, person_id, feature_id
Nun möchte ich Personen suchen, die zwei oder mehrere Eigenschaften haben.
Mir sind nun zwei Lösungen eingefallen:
Gibt es noch eine elegantere Lösung?
Ja.
Wenn nein, welche meiner Lösungen wäre eurer Meinung nach zu bevorzugen.
Sowieso keine von beiden, da ein Selfjoin nicht besonders gut skaliert.
Freundliche Grüße
Vinzenz
moin,
deine abfragen sind beide auch fachlich falsch, zumindestens nach dem was du als anforderung geschrieben hast.
1.Lösung
SELECT p.*
FROM People p
WHERE (SELECT COUNT(*)
FROM Personfeature pf
WHERE pf.person_id = p.id
) >= 2
;
2.Lösung
SELECT p.*
FROM People p
WHERE p.id IN (SELECT pf.id
FROM Personfeature pf
GROUP BY pf.person_id
HAVING COUNT(*) > 1
)
;
probiere beide aus, schaue welche schneller ausgeführt wird. indexe sollten allerdings auf den fremdschlüsseln liegen, wobei ich auch davon ausgehen, dass ein UNIQUE INDEX auf den spalten person_id und feature_id liegt.
Ilja